perm filename GCBIB[MAC,LSP] blob
sn#287427 filedate 1977-06-12 generic text, type C, neo UTF8
COMMENT ⊗ VALID 00048 PAGES
C REC PAGE DESCRIPTION
C00001 00001
C00003 00002
C00006 00003
C00010 00004
C00013 00005
C00016 00006
C00019 00007
C00021 00008
C00023 00009
C00024 00010
C00027 00011
C00029 00012
C00033 00013
C00035 00014
C00038 00015
C00039 00016
C00042 00017
C00044 00018
C00046 00019
C00049 00020
C00052 00021
C00058 00022
C00061 00023
C00063 00024
C00066 00025
C00068 00026
C00071 00027
C00074 00028
C00077 00029
C00080 00030
C00083 00031
C00086 00032
C00089 00033
C00091 00034
C00095 00035
C00099 00036
C00102 00037
C00105 00038
C00107 00039
C00109 00040
C00113 00041
C00117 00042
C00120 00043
C00122 00044
C00125 00045
C00127 00046
C00129 00047
C00131 00048
C00133 ENDMK
C⊗;
;;; **************************************************************
;;; ***** MACLISP ****** GARBAGE COLLECTOR AND ALLOCATION STUFF **
;;; **************************************************************
;;; ** (C) COPYRIGHT 1977 MASSACHUSETTS INSTITUTE OF TECHNOLOGY **
;;; ****** THIS IS A READ-ONLY FILE! (ALL WRITES RESERVED) *******
;;; **************************************************************
PGBOT GC
SUBTTL GRABBAGE COLLECTORS AND RELATED ITEMS
GCRET: TDZA A,A ;GC WITH NORET=NIL
GCNRT: MOVEI A,TRUTH ;GC WITH NORET=T
HRRI T,UNBIND ;EXPECTS FLAG IN LH OF T
PUSH P,T
JSP T,SPECBIND
0 A,VNORET
JRST AGC
GC: PUSH P,[333333,,FALSE] ;SUBR 0 - USER ENTRY TO GC
JRST AGC ;TO UNDERSTAND THE 3'S, SEE GSTRT7
MINCEL==6*NFF ;MIN NUMBER WORDS TO RECLAIM FOR EACH SPACE
IFG 40-MINCEL, MINCEL==40
IFN KA10+KI10,[
GCCNT: ;FREELIST COUNTING LOOP TO RUN IN AC'S
OFFSET -.
NIL ;SO THAT THE FOLLOWING INS WILL STOP ON NIL
GCCNT1: SKIPE TT,(TT)
GCCNT4: AOJA GCCNT0,.-1 ;OR MAYBE AOBJN
JRST GCP4A
LPROG3==:.-1
GCCNT0:
OFFSET 0
.HKILL GCCNT1 GCCNT4 GCCNT0
] ;END OF IFN KA10+KI10
IFN KL10,[
GCCNT1: SKIPE VGCDAEMON ;FREELIST COUNTING LOOP
JRST GCCNT6
SKIPE TT,(TT)
AOBJN GCCNT0,.-1 ;SHORT ONE FOR JUST SEEING WHETHER >MINCEL
JRST GCP4A
GCCNT6: SKIPE TT,(TT)
AOJA GCCNT0,.-1 ;LONG ONE FOR COUNTING FOR GCDAEMON
JRST GCP4A
GCCNT0==:AR1
] ;END OF IFN KL10
;;; *********** GARBAGE COLLECTOR **********
SUBTTL GC - INITIALIZATION
WHL==:USELESS*QIO*ITS ;FLAG FOR WHO-LINE STUFF
XCTPRO
AGC4: HRROS NOQUIT
NOPRO
SUBI A,2 ;ENTRY FROM FWCONS,FPCONS
PUSH P,A
XCTPRO
AGC: HRROS NOQUIT
NOPRO
SKIPE ALGCF ;CANT SUCCESSFULLY GC WHILE IN ALLOC
JRST ALERR
AGC1: ;MUST HAVE DONE HRROS NOQUIT BEFORE COMING HERE
10% .SUSET [.RRUNT,,GCTM1]
MOVEM NACS+1,GCNASV
10$ SETZ NACS+1,
10$ RUNTIM NACS+1, ;GET RUNTIME IN MILLSECS.
10$ MOVEM NACS+1,GCTM1
MOVE NACS+1,[UUOH,,GCUUSV]
BLT NACS+1,GCUUSV+LUUSV-1 ;SAVE UUOH STUFF, IN CASE STRT IS USED
MOVE NACS+1,[NACS+2,,GCNASV+1]
BLT NACS+1,GCNASV+17-<NACS+1> ;SAVE NON-MARKED AC'S
MOVEI NACS+1,GCACSAV
BLT NACS+1,GCACSAV+NACS ;BLT AWAY ARG ACS (AND NIL) INTO PROTECTED PLACE
Q$ SETZM GCFXP
SETZ R,
REPEAT NFF,[
SKIPN FFS+.RPCNT ;FIGURE OUT WHICH SPACE(S) EMPTY
TLO R,400000←-.RPCNT
] ;END OF REPEAT NFF
SKIPN FFY2 ;IF WE RAN OUT OF SYMBOL BLOCKS,
TLO R,400000←<-FFY+FFS> ; THEN CREDIT IT TO SYMBOLS
MOVN D,R ;THIS IS A STANDARD HACK TO KILL ONE BIT
TDZE R,D ;SKIP IF THERE WERE NO BITS
JUMPE R,GCGRAB ;JUMP IF EXACTLY ONE BIT ON
AGC1Q: SETZM GCRMV
AOSE IRMVF ;IF OVERRIDE IS ON, THEN
SKIPE VGCTWA
SETOM GCRMV ;DO REMOVAL ANYHOW.
MOVNI TT,20 ;TOP 40 BITS OF WORD ON
JSP F,GCINBT ;INIT MARK BITS FOR LIST, FIXNUM, ETC.
MOVE T,[SFSSIZ,,OFSSIZ] ;SAVE AWAY OLD SIZES OF SPACES
BLT T,OSASIZ ; (USED FOR ARG TO GC-DAEMON)
MOVE T,VGCDAEMON
IOR T,GCGAGV
IFE WHL, JUMPE T,GCP6
IFN WHL, JUMPE T,GCP5
KAKI MOVSI R,GCCNT
KAKI BLT R,LPROG3
KAKI SKIPN VGCDAEMON
KAKI HRLI GCCNT4,(AOBJN GCCNT0,)
MOVNI R,NFF ;MAY OR MAY NOT HAVE BIGNUMS OR HUNKS
GCP4: SETZ GCCNT0,
SKIPGE FFS+NFF(R)
JRST GCP4B
SKIPN VGCDAEMON
MOVSI GCCNT0,-MINCEL
SKIPE TT,FFS+NFF(R)
AOJA GCCNT0,GCCNT1
GCP4A: TLZ GCCNT0,-1
HRRZ F,GCWORN+NFF(R) ;ACCOUNT FOR LENGTHS OF ITEMS
IMULI GCCNT0,(F)
CAIGE GCCNT0,MINCEL ;IF LESS THEN MINCEL, THEN FREELIST WAS
SETZM FFS+NFF(R) ; "PRACTICALLY EMPTY" AND DESERVES SOME BLAME
GCP4B: HRLM GCCNT0,NFFS+NFF(R)
AOJL R,GCP4
;FALLS THROUGH
;FALLS IN
;;; PDLS ARE SAFE
IFN WHL,[
GCP5: MOVE F,GCWHO
SKIPE GCGAGV
JRST GSTRT0
TRNN F,1
JRST GCP6
JRST GSTR0A
] ;END OF IFN WHL
IFE WHL,[
SKIPN GCGAGV
JRST GCP6
] ;END OF IFE WHL
GSTRT0: STRT 17,[SIXBIT \↑M;GC DUE TO !\]
GSTR0A: SETZB TT,D ;FIGURE OUT REASON FOR GC
HLRZ T,(P)
CAIN T,111111 ;WAS IT INITIAL STARTUP? (SEE LISP)
MOVEI TT,[SIXBIT \STARTUP!\]
CAIN T,333333 ;WAS IT USER CALLING GC FUNCTION?
MOVEI TT,[SIXBIT \USER!\]
CAIN T,444444 ;WAS IT ARRAYS?
MOVEI TT,[SIXBIT \ARRAY RELOCATION!\]
Q$ CAIN T,555555 ;I/O CHANNELS?
Q$ MOVEI TT,[SIXBIT \I/O CHANNELS!\]
JUMPN TT,GSTRT8
MOVNI T,NFF ;NONE OF THOSE HYPOTHESES WORK
GSTRT1: SKIPN FFS+NFF(T) ;MAYBE SOME STORAGE SPACE RAN OUT
SKIPA TT,T
ADDI D,1
AOJL T,GSTRT1
JUMPE TT,GSTRT7 ;NO, THAT WASN'T IT
IFN WHL, SKIPN GCGAGV
.ALSO, JRST GSTRT4
MOVNI T,NFF ;YES, IT WAS. PRINT MOBY MESSAGE!
SETZ R,
GSTRT2: SKIPE FFS+NFF(T)
JRST GSTRT5
JUMPE R,GSTRT3
CAIE D,NFF-2
STRT 17,[SIXBIT \, !\]
CAMN T,TT
STRT 17,[SIXBIT \ AND !\]
GSTRT3: SETO R,
STRT 17,@GSTRT9+NFF(T)
GSTRT5: AOJL T,GSTRT2
STRT 17,[SIXBIT \ SPACE!\]
CAIE D,NFF-1
STRT 17,[SIXBIT \S!\]
IFN WHL, GSTRT4: MOVE TT,GSTRT9+NFF(TT)
JRST GSTRT6
GSTRT7: MOVEI TT,[SIXBIT \ ? !\] ;I DON'T KNOW WHY WE'RE HERE!
GSTRT8:
IFN WHL,SKIPE GCGAGV
STRT 17,(TT) ;PRINT REASON
GSTRT6:
IFN WHL,[
TRNN F,1
JRST GCWHL9
MOVE D,(TT)
MOVE R,1(TT)
ROTC D,-22
MOVSI F,(SIXBIT \!\)
MOVE T,[220600,,D]
GCWHL2: ILDB TT,T
CAIE TT,'!
JRST GCWHL2
DPB NIL,T
GCWHL3: IDPB NIL,T
TLNE T,770000
JRST GCWHL3
HRLI D,(SIXBIT \GC:\)
MOVE T,[-6,,GCWHL6]
.SUSET T
GCWHL9:
] ;END OF IFN WHL
;FALLS THROUGH
;;; PDLS ARE SAFE
SUBTTL GC - MARK THE WORLD
;FALLS IN
GCP6: HRROS MUNGP ;STARTING TO MUNG SYMBOL/SAR MARK BITS
MOVE A,[<-20>←-NUNMRK] ;PRE-PROTECT CERTAIN
ANDM A,BTBLKS ; RANDOM LIST CELLS
MOVNI R,NACS+1 ;PROTECT CONTENTS OF MARKED ACS
GCP6Q0: HRRZ A,GCACSAV+NACS+1(R)
JSP T,GCMARK
AOJL R,GCP6Q0
HRRZ R,C2
ADDI R,1
GCP6Q1: HRRZ A,(R) ;CAUSES MARKING OF CONTENTS
JSP T,GCMARK ; OF ACS AT TIME OF GC, AND OF REG PDL
CAIGE R,(P)
AOJA R,GCP6Q1
MOVEI R,LPROTE-1
GCP6Q2: MOVEI A,BPROTE(R) ;PROTECT PRECIOUS STUFF
JSP T,GCMARK
SOJGE R,GCP6Q2
IFN BIGNUM,[
MOVEI R,LBIGPRO-1
GCP6Q3: MOVEI A,BBIGPRO(R)
JSP T,GCMARK
SOJGE R,GCP6Q3
] ;END OF IFN BIGNUM
MOVSI R,TTS<GC>
IORM R,DEDSAR+TTSAR ;PROTECT DEDSAR
IORM R,DBM+TTSAR ;PROTECT DEAD BLOCK MARKER
HRRZ R,SC2
GCP6Q4: HRRZ A,(R)
JSP T,GCMARK ;MARK SAVED VALUES ON SPEC PDL
CAIGE R,(SP)
AOJA R,GCP6Q4
SKIPN R,INTAR
JRST GCP6Q6
GCP6Q5: MOVE A,INTAR(R)
JSP T,GCMARK
SOJG R,GCP6Q5
GCP6Q6: ;PROTECT INTERRUPT FUNCTIONS
IFE QIO,[
MOVEI R,LUINTTB-1
GCP6Q7: SKIPE A,@UINTTB(R)
JSP T,GCMARK
SOJGE R,GCP6Q7
] ;END OF IFE QIO
IFN QIO,[
IRP Z,,[0,1,2]X,,[ALARMCLOCK,AUTFN,UDF]
MOVEI R,NUINT!Z
SKIPE A,V!X(R)
JSP T,GCMARK
SOJG R,.-2
TERMIN
SKIPE A,VMERR
JSP T,GCMARK
] ;END OF IFN QIO
IFN LHFLAG,[
SKIPN D,LHSGLK ;SKIP IF ANY LH SEGMENTS
JRST GCP6R0 .SEE LHVBAR
GCP6Q8: MOVEI F,(D) ;CREATE AOBJN POINTER INTO SEGMENT
LSH F,SEGLOG
HRLI F,-SEGSIZ
GCP6Q9: HLRZ A,(F) ;MARK FROM ALL ENTRIES IN THAT SEGMENT
JSP T,GCMARK
HRRZ A,(F)
JSP T,GCMARK
AOBJN F,GCP6Q9
LDB D,[SEGBYT,,GCST(D)] ;FOLLOW LINKED LIST OF SEGMENTS
JUMPN D,GCP6Q8
GCP6R0:
] ;END OF IFN LHFLAG
;FALLS THROUGH
;;; PDLS ARE SAFE
;FALLS IN
SKIPN GCRMV
JRST GCP6B1
JSP R,GCGEN ;IF DOING TWA REMOVAL, TRY MARKING FROM
GCP8I ;NON-TRIVIAL P-LISTS OF CURRENT OBARRAY
JRST GCP6B2
GCP6B1: MOVE A,VOBARRAY
JSP TT,$GCMKAR ;OTHERWISE, JUST MARK OBARRAY BUCKETS
GCP6B2: MOVEI A,OBARRAY
CAME A,VOBARRAY
JSP TT,$GCMKAR
MOVE R,GCMKL
GCP6A: JUMPE R,GCP6D
HLRZ A,(R)
MOVE D,ASAR(A)
TLNN D,AS<GCP> ;IF ARRAY POINTER HAS "GC ME" BIT SET,
JRST GCP6F
TLNE D,AS<OBA> ;MORE CHECKING ON OBARRAYS
JRST GCP6F0
GCP6F1: JSP TT,GCMKAR ; THEN MARK FROM ARRAY ENTRIES
GCP6F: HRRZ R,(R)
HRRZ R,(R)
JRST GCP6A
GCP6F0: CAMN A,VOBARRAY ; AND IF THIS ISN'T THE CURRENT OBARRAY,
SKIPN GCRMV ; OR IT IS, BUT WE ARENT DOING GCTWA REMOVAL,
JRST GCP6F1
JRST GCP6F
GCP6D:
IFN QIO,[
MOVE A,V%TYI
JSP TT,$GCMKAR
MOVE A,V%TYO
JSP TT,$GCMKAR
] ;END OF IFN QIO
SKIPN R,PROLIS
GCP6D1: JUMPE R,GCP6H ;PROTECT READ-MACRO
HLRZ A,(R) ; FUNCTIONS (CAN'T JUST GCMARK WHOLE
HLRZ A,(A) ; PROLIS - DON'T WANT TO PROTECT
JSP T,GCMARK ; READTABLE SARS)
HRRZ R,(R)
JRST GCP6D1
GSTRT9: [SIXBIT \LIST!\] .SEE GCWORRY
[SIXBIT \FIXNUM!\] .SEE GCPNT
[SIXBIT \FLONUM!\]
DB$ [SIXBIT \DOUBLE!\]
CX$ [SIXBIT \COMPLEX!\]
DX$ [SIXBIT \DUPLEX!\]
BG$ [SIXBIT \BIGNUM!\]
[SIXBIT \SYMBOL!\]
IRP X,,[4,8,16,32,64,128,256,512,1024]
IFE .IRPCNT-HNKLOG, .ISTOP
[SIXBIT \HUNK!X!!\]
TERMIN
[SIXBIT \ARRAY!\]
IFN WHL,[
GCWHL6: .RWHO1,,GCWHO1
.RWHO2,,GCWHO2
.RWHO3,,GCWHO3
.SWHO1,,[.BYTE 8 ? 66 ? 0 ? 366 ? 0 ? .BYTE]
.SWHO2,,D
.SWHO3,,R
] ;IFN WHL
;;; PDLS ARE SAFE
SUBTTL GC - CONSIDER THE EFFECTS OF AN ARRAY DISAPPEARING
;;; UPDATE THE GCMKL BY SPLICING OUT ARRAYS TO BE SWEPT.
;;; IF ANY SUCH ARRAYS ARE OPEN FILES, CLOSE THEM.
CGCMKL:
GCP6H: SKIPN F,GCMKL
JRST GCP7
JSP A,GCP6H0
GCP6H1: HLRZ A,(F)
TDNE TT,TTSAR(A)
JRST GCP6G
Q$ TDNE T,ASAR(A)
Q$ JRST GCP6H7
Q$ GCP6H8:
ANDCAM TT,TTSAR(A)
IORM R,TTSAR(A)
MOVEI B,ADEAD
EXCH B,ASAR(A)
TLNN B,AS<RDT>
JRST GCP6G
MOVEI AR1,PROLIS ;JUST KILLED A READTABLE
GCP6H3: HRRZ AR2A,(AR1) ; - CLEAN UP PROLIS
GCP6H4: JUMPE AR2A,GCP6G
HLRZ C,(AR2A)
HRRZ C,(C)
HLRZ C,(C)
CAIE C,(A)
JRST GCP6H5
HRRZ AR2A,(AR2A)
HRRM AR2A,(AR1)
JRST GCP6H4
GCP6H5: MOVEI AR1,(AR2A)
JRST GCP6H3
GCP6G: HRRZ F,(F)
HRRZ F,(F)
JUMPN F,GCP6H1
JRST GCP7
GCP6H0: MOVSI T,AS<JOB+FIL> ;SET UP SOME ACS FOR THE GCMKL-LOOK LOOP
MOVE R,[TTDEAD]
MOVSI TT,TTS<CN+GC>
JRST (A)
;;; PDLS ARE SAFE
IFN QIO,[
;;; CLEAN UP AND CLOSE A FILE WHEN GARBAGE COLLECTED
GCP6H7: MOVE B,TTSAR(A) ;ABOUT TO GC A FILE ARRAY
TLNE B,TTS<CL> ;IGNORE IF ALREADY CLOSED
JRST GCP6H8
PUSH P,F
IFN JOBQIO,[
HLL B,ASAR(A)
TLNE B,AS<JOB>
JRST GCP6J1
] ;END OF IFN JOBQIO
PUSHJ P,ICLOSE ;OTHERWISE CLOSE THE FILE
MOVEI R,[SIXBIT \↑M;FILE CLOSED: !\]
GCP6H2: SKIPN GCGAGV
JRST GCP6H9
STRT 17,(R)
HLRZ A,@(P)
HRRZ AR1,VMSGFILES
TLO AR1,200000
HRROI R,$TYO
PUSHJ P,PRINTA
GCP6H9: POP P,F
JSP A,GCP6H0 ;RE-INIT MAGIC CONSTANTS IN ACS
HLRZ A,(F)
JRST GCP6H8
IFN JOBQIO,[
;;; CLEAN UP AND CLOSE AN INFERIOR PROCEDURE WHEN GARBAGE COLLECTED
GCP6J1: MOVEI R,[SIXBIT \↑M;FOREIGN JOB FLUSHED: !\]
SKIPN T,J.INTB(B)
JRST GCP6J3
MOVEI R,[SIXBIT \↑M;INFERIOR JOB FLUSHED: !\]
.CALL GCP6J9
.VALUE
.UCLOSE TMPC,
JFFO T,.+1
MOVNS TT
SETZM JOBTB+21(TT)
GCP6J3: MOVSI T,TTS<CL>
ANDCAM T,TTSAR(A)
JRST GCP6H2
GCP6J9: SETZ
SIXBIT \OPEN\ ;OPEN FILE (INFERIOR PROCEDURE)
1000,,TMPC ;CHANNEL NUMBER
,,F.DEV(B) ;DEVICE NAME (USR)
,,F.FN1(B) ;FILE NAME 1 (UNAME)
400000,,F.FN2(B) ;FILE NAME 2 (JNAME)
] ;END OF IFN JOBQIO
] ;END OF IFN QIO
;;; PDLS ARE SAFE
SUBTTL GC - TWA REMOVAL
GCP7: HRRZ A,GCMKL
JSP T,GCMARK
HRRZ A,PROLIS
JSP T,GCMARK
SKIPN GCRMV
JRST GCSWP
JSP R,GCGEN ;IF DOING TWA REMOVAL, THEN WIPE OUT
GCP8G ; T.W.A.'S AND THEN MARK BUCKETS
MOVE A,VOBARRAY
JSP TT,$GCMKAR
;FALLS THROUGH
;;; PDLS ARE UNSAFE
SUBTTL GC - SWEEP THE WORLD
;FALLS IN
GCSWP: .SEE KLINIT ;WHICH CLOBBERS NEXT INSTRUCTION
Q$ MOVEM FXP,GCFXP ;WE ARE ABOUT TO CLOBBER THE PDL POINTERS
MOVNI SP,NFF ;NUMBER OF SPACES TO SWEEP
MOVEM SP,GC99
;MAJOR SWEEP LOOP OVER ALL SPACES
GCSW1:
IFN KA10+KI10,[
MOVE FXP,GCSWTB+NFF(SP) ;PUT INNER SWEEP LOOP IN AC'S
HLLZ FLP,FXP ; AND INITIALIZE COUNT
BLT FLP,(FXP)
SETZ FXP, ;FREELIST INITIALLY NIL
] ;END OF IFN KA10+KI10
KL SETZB A,FXP ;FXP HAS FREELIST, A HAS COUNT
SKIPN FLP,FSSGLK+NFF(SP)
JRST GCSW7
;MINOR SWEEP LOOP OVER ALL SEGMENTS IN A SPACE
GCSW2: MOVEM FLP,GC98
JRST @GCSW2A+NFF(SP) ;DISPATCH ON TYPE TO SEPARATE ROUTINES
GCSW2A: GCSWS ;LIST
GCSWS ;FIXNUM
GCSWS ;FLONUM
DB$ GCSWD ;DOUBLE
CX$ GCSWC ;COMPLEX
DX$ GCSWZ ;DUPLEX
BG$ GCSWS ;BIGNUM
GCSWY ;SYMBOL
REPEAT HNKLOG,[
IFL .RPCNT-4, GCSWH1 ;HUNKS OF LESS THAN 40 WORDS
.ELSE GCSWH2 ;HUNKS OF 40 WORDS OR MORE
] ;END OF REPEAT HNKLOG
GCSWA ;SARS
IFN .-GCSW2A-NFF, WARN [WRONG LENGTH TABLE]
GCSW5: MOVE SP,GC99
MOVE FLP,GC98
LDB FLP,[SEGBYT,,GCST(FLP)]
JUMPN FLP,GCSW2
GCSW7:
KAKI HRRZ A,@GCSW7A+NFF(SP)
HRRM FXP,FFS+NFF(SP) ;SAVE FREELIST - DON'T DISTURB SIGN BIT
HRRZ B,GCWORN+NFF(SP)
IMULI A,(B) ;ACCOUNT FOR SIZE OF OBJECTS IN THIS SPACE
HRRM A,NFFS+NFF(SP) ;SAVE COUNT OF WORDS COLLECTED
AOSGE SP,GC99
JRST GCSW1
HRRZS MUNGP ;WE HAVE UNDONE MUNGING OF BITS
MOVSI F,TTS<CN+GC>
ANDCAM F,DEDSAR ;MUST CLEAR BITS IN DEDSAR
JSP T,GCACR ;RESTORE ACCUMULATORS
JRST GCPNT ;NEXT PRINT STATISTICS
IFN KA10+KI10,[
;TABLE OF SWEEPERS FOR RUNNING IN ACS AND THE LAST LOCATIONS TO LOAD THEM INTO
GCSWTB: GCFSSWP,,LPROG1 ;LIST
GCFSSWP,,LPROG1 ;FIXNUMN
GCFSSWP,,LPROG1 ;FLONUM
DB$ GCHSW1,,LPROGH ;DOUBLE
CX$ GCHSW1,,LPROGH ;COMPLEX
DX$ GCHSW1,,LPROGH ;DUPLEX
BG$ GCFSSWP,,LPROG1 ;BIGNUM
GSYMSWP,,LPROG6 ;SYMBOL
REPEAT HNKLOG,[
IFL .RPCNT-4, GCHSW1,,LPROGH ;HUNKS OF LESS THAN 40 WORDS
.ELSE GCHSW2,,LPROGK ;HUNKS OF 40 WORDS OR MORE
] ;END OF REPEAT HNKLOG
GSARSWP,,LPROG4 ;SARS
IFN .-GCSWTB-NFF, WARN [WRONG LENGTH TABLE]
;TABLE OF AC FOR EACH SWEEPER WHICH HOLDS COUNT OF OBJECTS SWEPT
GCSW7A: GFSCNT ;LIST
GFSCNT ;FIXNUM
GFSCNT ;FLONUM
DB$ GHCNT1 ;DOUBLE
CX$ GHCNT1 ;COMPLEX
DX$ GHCNT1 ;DUPLEX
BG$ GFSCNT ;BIGNUM
GYCNT ;SYMBOL
REPEAT HNKLOG,[
IFL .RPCNT-4, GHCNT1 ;HUNK OF LESS THAN 40 WORDS
.ELSE GHCNT2 ;HUNKS OF 40 WORDS OR MORE
] ;END OF REPEAT HNKLOG
GSCNT ;SARS
IFN .-GCSW7A-NFF, WARN [WRONG LENGTH TABLE]
] ;END OF IFN KA10+KI10
GCSWS: MOVE P,GCST(FLP) ;GET SHIFTED ADDRESS OF BIT BLOCK
LSH P,SEGLOG-5 ;SHIFT BACK TO FORM WORD ADDRESS
HRLI P,-BTBSIZ ;MAKE AOBJN POINTER OVER WORDS OF BITS
LSH FLP,SEGLOG
HRLI FLP,-40 ;40 CELLS PER WORD OF BITS
KAKI JRST GFSP1
;FXP HAS RUNNING FREELIST
;FLP HAS AOBJN POINTER OVER CELLS
;P HAS AOBJN POINTER OVER WORDS OF BITS
GCFSSWP: ;SWEEPER FOR LIST, FIXNUM, FLONUM, BIGNUM
KAKI OFFSET -. ;RELOCATED TO ACS FOR KA AND KI
GFSP1: SKIPN SP,(P) ;GET A WORD OF MARK BITS
JRST GFSP5 ;IF ALL 40 WORDS MARKED, THIS SAVES TIME
GFSP2: JUMPGE SP,GFSP4 ;JUMP IF SINGLE WORD MARKED
HRRZM FXP,(FLP) ;ELSE CHAIN INTO FREE LIST
HRRZI FXP,(FLP)
KAKI GFSCNT: AOJ .,0 ;RH COUNTS RECLAIMED CELLS
KL ADDI A,1
GFSP4: ROT SP,1 ;ROTATE NEXT MARK BIT UP
AOBJN FLP,GFSP2 ;COUNT OFF 40 WORDS
TLOA FLP,-40 ;RESET 40-WORD COUNT IN AOBJN POINTER
GFSP5: ADDI FLP,40 ;SKIP OVER 40 WORDS IN SWEEP
AOBJN P,GFSP1 ;<BTBSIZ> BLOCKS OF 40 WORDS
JRST GCSW5
KAKI LPROG1==:.-1
KAKI OFFSET 0
KAKI .HKILL GFSP1 GFSP2 GFSCNT GFSP4 GFSP5
GCSWY: LSH FLP,SEGLOG
HRLI FLP,-SEGSIZ
KL MOVEI GYSP7,(300,,0) ;3.8=PURE, 3.7=COMPILED CODE REFS
KAKI JRST GYSP1
KL GYSP7==:0
GSYMSWP: ;SWEEPER FOR SYMBOL SPACE
KAKI OFFSET -.
KAKI GYSP7: (300,,0) ;3.8=PURE, 3.7=COMPILED CODE REFS (NOTE: TSNE WITH ITSELF ALWAYS SKIPS)
GYSP1: HLRZ SP,(FLP)
TRZN SP,1 ;IF MARKED,
TSNE GYSP7,(SP) ; OR IF PURE OR COMPILED CODE NEEDS IT,
JRST GYSP3 ; THEN DO NOT SWEEP UP
JUMPN SP,GYSP5 ;IF NON-NIL LEFT HALF, RECLAIM THE SYMBOL BLOCK
GYSP2: HRRZM FXP,(FLP) ;CHAIN ONTO FREELIST
HRRZI FXP,(FLP)
GYCNT:
KAKI AOJ .,0
KL ADDI A,1 ;INCREMENT OBJECT COUNT
GYSP3: HRLM SP,(FLP)
AOBJN FLP,GYSP1
JRST GCSW5
KAKI LPROG6==:.-1
KAKI OFFSET 0
KAKI .HKILL GYSP1 GYSP2 GYSP3 GYSP7 GYCNT
;;; PART OF SYMBOL SWEEPER - RESTORES A SYMBOL BLOCK TO FFY2.
;;; ALSO ATTEMPTS TO RETURN THE VALUE CELL IF IT HAS ONE.
GYSP5: EXCH SP,FFY2 ;RETURN SYMBOL BLOCK TO FREELIST
EXCH SP,@FFY2
TLZ SP,-1 ;MAYBE TRY TO RETURN A VALUE CELL
CAIE SP,SUNBOUND
JRST GYSP5A
SETZ SP,
JRST GYSP2
GYSP5A: CAIL SP,BXVCSG+NXVCSG*SEGSIZ
JRST GYSP5B ;CAN ONLY RETURN CELLS IN VC SPACE
EXCH SP,FFVC
MOVEM SP,@FFVC
GYSP5B: SETZ SP,
JRST GYSP2
IFN HNKLOG+DBFLAG+CXFLAG,[
GCSWD:
GCSWC:
GCSWZ:
GCSWH1: HRRZ P,GCWORN+NFF(SP) ;GET SIZE OF OBJECTS
KAKI HRRI GH1SP4,(P)
KL MOVEI B,(P)
SUBI P,1
KAKI HRRI GH1SP5,(P)
KL MOVEI C,(P)
HRRZ P,GCWORN+NFF(SP)
MOVNI SP,40
IDIVM SP,P
KAKI HRRI GH1SP6,(P) ;BITS PER BIT BLOCK WORD
KL MOVEI AR1,(P)
MOVE P,GCST(FLP) ;GET SHIFTED ADDRESS OF BIT BLOCK
LSH P,SEGLOG-5 ;SHIFT BACK TO FORM WORD ADDRESS
HRLI P,-BTBSIZ ;MAKE AOBJN POINTER OVER WORDS OF BITS
LSH FLP,SEGLOG ;MAKE AOBJN POINTER OVER CELLS
KAKI HRLI FLP,(GH1SP6)
KL HRLI FLP,(AR1)
KAKI JRST GH1SP1
;FXP HAS RUNNING FREELIST
;FLP HAS AOBJN POINTER OVER CELLS
;P HAS AOBJN POINTER OVER WORDS OF BITS
GCHSW1:
KAKI OFFSET -.
GH1SP1: MOVE SP,(P)
GH1SP2: JUMPGE SP,GH1SP4
HRRZM FXP,(FLP)
HRRZI FXP,(FLP)
IFN KA10+KI10,[
GHCNT1: AOJ .,0
GH1SP4: ROT SP,1←HNKLOG
GH1SP5: ADDI FLP,<1←HNKLOG>-1
AOBJN FLP,GH1SP2
GH1SP6: HRLI FLP,<-40>←-HNKLOG
] ;END OF IFN KA10+KI10
IFN KL10,[
ADDI A,1
GH1SP4: ROT SP,(B)
ADDI FLP,(C)
AOBJN FLP,GH1SP2
HRLI FLP,(AR1)
] ;END OF IFN KL10
AOBJN P,GH1SP1
JRST GCSW5
KAKI LPROGH==:.-1
KAKI OFFSET 0
KAKI .HKILL GH1SP1 GH1SP2 GHCNT1 GH1SP4 GH1SP5 GH1SP6
] ;END OF IFN HNKLOG+DBFLAG+CXFLAG
IFG HNKLOG-4,[
GCSWH2: HRRZ P,GCWORN+NFF(SP) ;GET SIZE OF OBJECTS
KAKI HRRI GH2SP5,(P)
KL MOVEI B,(P)
SUBI P,1
LSH P,-5
KAKI HRRI GH2SP7,(P) ;BITS PER BIT BLOCK WORD
KL MOVEI AR2A,(P)
HRRZ P,GCWORN+NFF(SP)
LSH P,-5
MOVNI SP,BTBSIZ
IDIVM SP,P
HRLI P,(P) ;MAKE AOBJN POINTER OVER WORDS OF BITS
MOVE SP,GCST(FLP)
LSH SP,SEGLOG-5
HRRI P,(SP)
LSH FLP,SEGLOG ;MAKE POINTER OVER CELLS
KAKI JRST GH2SP1
;FXP HAS RUNNING FREELIST
;FLP HAS AOBJN POINTER OVER CELLS
;P HAS AOBJN POINTER OVER WORDS OF BITS
GCHSW2:
KAKI OFFSET -.
GH2SP1: SKIPL (P) ;ONLY THE SIGN BIT OF A MARK WORD IS USED
JRST GH2SP5
HRRZM FXP,(FLP)
HRRZI FXP,(FLP)
IFN KA10+KI10,[
GHCNT2: AOJ .,0
GH2SP5: ADDI FLP,1←HNKLOG
GH2SP7: ADDI P,<<1←HNKLOG>-1>←-5
] ;END OF IFN KA10+KI10
IFN KL10,[
ADDI A,1
GH2SP5: ADDI FLP,(B)
ADDI P,(AR2A)
] ;END OF IFN KL10
AOBJN P,GH2SP1
JRST GCSW5
KAKI LPROGK==:.-1
KAKI OFFSET 0
KAKI .HKILL GH2SP1 GH2SP2 GHCNT2 GH2SP5 GH2SP7
] ;END OF IFG HNKLOG-4
GCSWA: LSH FLP,SEGLOG
HRLI FLP,-SEGSIZ/2
KL MOVSI B,(TTS<CN+GC>,,)
KL MOVSI C,(TTS<GC>,,)
JRST GSSP1
GSARSWP: ;SPECIAL SWEEPER FOR SARS
KAKI OFFSET -.
GSSP0: ADDI FLP,1
GSSP1:
KAKI TDNN GSSP7,TTSAR(FLP) ;TEST IF SAR MARKED (OR OTHERWISE NEEDED)
KL TDNN B,TTSAR(FLP)
KAKI AOJA GSCNT,GSSP2 ;NO, COUNT IT AS SWEPT
KL AOJA A,GSSP2
KAKI ANDCAM GSSP8,TTSAR(FLP) ;YES, TURN OFF MARK BIT
KL ANDCAM C,TTSAR(FLP)
AOBJN FLP,GSSP0 ; AND TRY NEXT ONE
JRST GCSW5
GSSP2: HRRZM FXP,ASAR(FLP) ;CHAIN INTO FREE LIST
HRRZI FXP,ASAR(FLP)
AOBJN FLP,GSSP0
JRST GCSW5
KAKI GSSP7: TTS<CN+GC>,,
KAKI GSSP8: TTS<GC>,,
KAKI GSCNT: 0
KAKI LPROG4==:.-1
KAKI OFFSET 0
KAKI .HKILL GSSP0 GSSP1 GSSP2 GSSP7 GSSP8 GSCNT
;;; PDLS ARE SAFE
SUBTTL GC - MAKE SURE ENOUGH WAS RECLAIMED
GCPNT: SKIPN GCGAGV
JRST GCE0
SETZM GC99 ;GC99 COUNTS ENTRIES PRINTED
MOVNI F,NFF
GCPNT1: HRRZ T,NFFS+NFF(F)
SKIPN TT,SFSSIZ+NFF(F)
JRST GCPNT6
SOSLE GC99
JRST GCPNT2
STRT 17,[SIXBIT \↑M; !\] ;TERPRI-; EVERY THIRD ONE
MOVEI D,3
MOVEM D,GC99
GCPNT2: PUSHJ P,STGPNT
STRT 17,@GSTRT9+NFF(F)
CAME F,XC-1 ;COMMA AFTER EACH BUT LAST
STRT 17,[SIXBIT \, !\]
GCPNT6: AOJL F,GCPNT1
STRT [SIXBIT \ WORDS FREE!\]
;FALLS THROUGH
;;; PDLS ARE SAFE
SUBTTL GC - CLEANUP AND TERMINATION
;FALLS IN
GCE0: MOVNI F,NFF
GCE0C0: MOVE AR2A,MFFS+NFF(F)
TLNN AR2A,-1
JRST GCE0C1
HRRZ AR1,SFSSIZ+NFF(F)
FSC AR1,233 ;FIXNUM TO FLONUM CONVERSION
FMPR AR1,AR2A
MULI AR1,400 ;FLONUM TO FIXNUM CONVERSION
ASH AR2A,-243(AR1)
GCE0C1: SKIPGE FFS+NFF(F)
JRST GCE0C5
CAIGE AR2A,MINCEL
MOVEI AR2A,MINCEL ;MUST SATISFY ABSOLUTE MIN OF<MINCEL> CELLS
GCE0C5: MOVEM AR2A,ZFFS+NFF(F)
HRRZ TT,NFFS+NFF(F)
CAIGE TT,(AR2A) ;ALSO MUST SATISFY USER'S MIN
PUSHJ P,GCWORRY ;IF NOT, MUST WORRY ABOUT IT
GCE0C2: AOJL F,GCE0C0
MOVEI AR2A,1
SKIPN FFY2
PUSHJ P,GRABWORRY ;REMEMBER, F IS ZERO HERE
SKIPN FFY2
JRST GCLUZ
MOVNI F,NFF ;IF WE RECLAIMED LESS THAN ABSOLUTE
GCE0C3: HRRZ TT,NFFS+NFF(F) ; MINIMUM FOR ANY SPACE,
SKIPGE FFS+NFF(F)
JRST GCE0C9
CAIGE TT,MINCEL ; WE ARE OFFICIALLY DEAD
JRST GCLUZ
GCE0C9: AOJL F,GCE0C3
SKIPE PANICP
JRST GCE0C7
MOVNI F,NFF ;NOW SEE IF WE EXCEEDED MAXIMUM
GCE0C6: MOVE TT,SFSSIZ+NFF(F)
CAMG TT,XFFS+NFF(F)
JRST GCE0K3
Q$ HRLZ D,GCMES+NFF(F)
Q$ HRRI D,1004 ;GC-OVERFLOW
Q% HRLZ A,GCMES+NFF(F)
Q% HRRI A,13. ;GC-OVERFLOW
PUSHJ P,UINT ;NOQUIT SET, SO INTERRUPT GETS STACKED
GCE0K3: AOJL F,GCE0C6
GCE0C7: MOVNI F,NFF
GCE0C4: MOVE TT,SFSSIZ+NFF(F)
CAMG TT,XFFS+NFF(F) ;IF A SPACE LOST TO GC-OVERFLOW,
JRST GCE0K2 ; DON'T MAKE IT LOSE FOR GC-LOSSAGE TOO
MOVEM TT,XFFS+NFF(F) ;JUST QUIETLY UPDATE ITS GCMAX
JRST GCE0K1
GCE0K2: HRRZ T,NFFS+NFF(F)
CAMGE T,ZFFS+NFF(F)
JRST GCMLOSE
GCE0K1: AOJL F,GCE0C4
IFE D10,[
HRRZ TT,NOQUIT
IOR TT,INHIBIT
IOR TT,VNORET
SKIPN TT
PUSHJ P,RETSP
] ;END OF IFE D10
SKIPE GCGAGV
STRT 17,STRTCR
;FALLS THROUGH
;;; PDLS ARE SAFE
;FALLS IN
SKIPN VGCDAEMON
JRST GCEND
MOVEI C,NIL ;CONS UP ARG FOR GCDAEMON
MOVEI D,NFF-1 ;WE CHECKED LENGTH OF FREELISTS SO
SETZ C, ; WE KNOW CONSES WON'T RE-INVOKE GC
GCE0E: MOVE TT,SFSSIZ(D) ;SIZE OF SPACE AFTER GC
PUSHJ P,CONS1FX
MOVE TT,OFSSIZ(D) ;SIZE OF SPACE BEFORE GC
PUSHJ P,CONSFX
HRRZ TT,NFFS(D) ;LENGTH OF FREELIST AFTER GC
CAIN D,FFX-FFS ;ALLOW FOR THE SPACE USED
SUBI TT,4*NFF ; TO CONS UP THE GC-DAEMON ARG
CAIN D,FFS-FFS
SUBI TT,6*NFF
PUSHJ P,CONSFX
HLRZ TT,NFFS(D) ;LENGTH OF FREELIST BEFORE GC
PUSHJ P,CONSFX
HRRZ A,GCMES(D) ;NAME OF SPACE
PUSHJ P,CONS
MOVE B,C
PUSHJ P,CONS
MOVE C,A
SOJGE D,GCE0E
JSR GCRSR .SEE GCRSR0
IFE QIO,[
HRLI A,20. ;INT NUMBER OF GC-DAEMON
PUSH P,A ;FOR GC PROTECTION ONLY
MOVSS A
PUSHJ P,UINT
JRST S1PAJ
] ;END OF IFE QIO
IFN QIO,[
HRLI A,1003 ;GC-DAEMON
PUSH P,A ;FOR INTERRUPT PROTECTION ONLY
PUSH FXP,D
MOVS D,A
PUSHJ P,UINT
POP FXP,D
JRST S1PAJ
] ;END OF IFN QIO
;;; GC MUST EITHER JRST TO GCEND, OR JSR TO GCRSR BEFORE EXITING.
;;; THIS ASSURES THAT GCTIM WILL PROPERLY REFLECT TIME SPENT IN GC.
GCEND: JSP NACS+1,GCACR
Q$ SETZM GCFXP
10% .SUSET [.RRUNT,,NACS+1]
10$ SETZ NACS+1,
10$ RUNTIM NACS+1,
IFN WHL, MOVEM NACS+1,GC98
SUB NACS+1,GCTM1
ADDM NACS+1,GCTIM ;UPDATE GCTIME FOR (STATUS GCTIME)
IFN WHL,[
SKIPE NACS+1,GCWHO
PUSHJ P,GCWHR
] ;IFN WHL
MOVE NACS+1,GCNASV
HRRZS NOQUIT
JRST CHECKI
;GCRSR: 0
GCRSR0: HRLM C,NOQUIT ;RESTORE ACS, AND CHECK FOR ANY
JSP NACS+1,GCACR ;DELAYED INTERRUPTS
Q$ SETZM GCFXP
10% .SUSET [.RRUNT,,NACS+1]
10$ SETZ NACS+1,
10$ RUNTIM NACS+1,
IFN WHL, MOVEM NACS+1,GC98
SUB NACS+1,GCTM1
ADDM NACS+1,GCTIM ;UPDATE GCTIME FOR (STATUS GCTIME)
IFN WHL,[
SKIPE NACS+1,GCWHO
PUSHJ P,GCWHR
] ;IFN WHL
MOVE NACS+1,GCNASV
PUSH P,A
HLRZ A,NOQUIT
PUSH P,GCRSR
HRRZS NOQUIT
JRST CHECKI
;;; ROUTINE TO INIT MARK BITS FOR LIST, FIXNUM, FLONUM, HUNK,
;;; AND BIGNUM SPACES. INIT BITS IN TT, RETURN ADDRESS IN F.
GCINBT: MOVEM TT,BBITSG
MOVE AR2A,[BBITSG,,BBITSG+1]
BLT AR2A,@MAINBITBLT ;BLT OUT MAIN BIT AREA
MOVE A,BTSGLK ;INITIALIZE ALL BIT BLOCKS
GCINB0: JUMPE A,(F)
MOVEI AR2A,(A)
LSH AR2A,SEGLOG ;GET ADDRESS OF SEGMENT
HRLI AR2A,(AR2A)
MOVEM TT,(AR2A)
AOJ AR2A,
MOVE T,GCST(A) ;GET END ADDRESS FOR BLT
LSH T,SEGLOG-5
TLZ T,-1
CAIE T,(AR2A)
BLT AR2A,-1(T) ;***BLT!***
LDB A,[SEGBYT,,GCST(A)]
JRST GCINB0
IFN WHL,[
GCWHR: TRNN NACS+1,2 ;SKIP IF GC STATISTICS DESIRED
JRST GCWHR2
MOVE NACS+2,GCTIM
IDIVI NACS+2,25000./4 ;GC TIME IN FORTIETHS OF A SECOND
MOVEM NACS+2,GCWHO2
MOVE NACS+2,GCTIM ;GC TIME
IMULI NACS+2,100. ; TIMES 100.
IDIV NACS+2,GC98 ; DIVIDED BY TOTAL RUNTIME
HRLM NACS+2,GCWHO2 ; EQUALS GC TIME PERCENTAGE
TRNE NACS+1,1
JRST GCWHR2
.SUSET [.SWHO2,,GCWHO2] ;JUST SET .WHO2 IF WHO VARS NOT PREVIOUSLY SAVED
GCWHR8: MOVE NACS+2,GCNASV+1 ;RESTORE ACS
MOVE NACS+3,GCNASV+2
POPJ P,
GCWHR2: MOVE NACS+2,[-3,,GCWHR9] ;RESTORE WHO VARS, POSSIBLY WITH
.SUSET NACS+2 ; GC STATISTICS CLOBBERED INTO GCWHO2
JRST GCWHR8
GCWHR9: .SWHO1,,GCWHO1
.SWHO2,,GCWHO2
.SWHO3,,GCWHO3
] ;IFN WHL
SUBTTL MISCELLANEOUS GC UTILITY ROUTINES
GCACR:
Q$ SKIPN GCFXP
Q$ MOVEM FXP,GCFXP
MOVE NIL,[GCACSAV+1,,1] ;RESTORE ALL ACS EXCEPT NACS+1
BLT NIL,NACS
MOVE NIL,[GCNASV+1,,NACS+2]
BLT NIL,17
MOVE NIL,GCACSAV
Q$ SETZM GCFXP .SEE CHNINT ;ETC.
JRST (NACS+1)
$GCMKAR: MOVE D,ASAR(A)
GCMKAR:
Q$ MOVE F,TTSAR(A)
SKIPL D,-1(D) ;MARK FROM ARRAY ENTRIES.
JRST (TT)
GCMKA1: HLRZ A,(D)
JSP T,GCMARK
HRRZ A,(D)
JSP T,GCMARK
AOBJN D,GCMKA1
Q% JRST (TT)
IFN QIO,[
JUMPE F,(TT)
TLNE F,TTS<TY>
TLNE F,TTS<IO>
JRST (TT)
MOVEI D,FB.BUF(F) ;FOR TTY INPUT FILE ARRAYS,
HRLI D,-NASCII/2 ; MUST MARK INTERRUPT FUNCTIONS
SETZ F,
JRST GCMKA1
] ;END OF IFN QIO
;;; GCGEN GENERATES NON-NULL BUCKETS OF THE CURRENT OBARRAY
;;; AND APPLIES A GIVEN FUNCTION TO THEM. IT IS CALLED AS
;;; JSP R,GCGEN
;;; FOO
;;; GCGEN WILL EFFECTIVELY DO A JRST FOO MANY TIMES,
;;; PASSING SOME NON-NULL OBARRAY BUCKET THROUGH ACCUMULATOR D.
;;; FOO IS EXPECTED TO RETURN BY DOING A JRST GCP8A.
;;; WHEN DONE, GCGEN RETURNS, SKIPPING OVER THE ADDRESS FOO.
GCGEN: MOVE F,@VOBARRAY .SEE ASAR
MOVE F,-1(F)
SUB F,R70+1
TLZ R,400000
GCP8A: TLCE R,400000
JRST GCP8A1
AOBJP F,1(R) ;EXIT
HLRZ D,(F)
JUMPN D,@(R)
JRST GCP8A
GCP8A1: HRRZ D,(F)
JUMPN D,@(R)
JRST GCP8A
;;; MARK AN S-EXPRESSION GIVEN IN A. TRACES IT COMPLETELY,
;;; MARKING ALL SUBITEMS BY SETTING A MARK BIT TO **ZERO**
;;; FOR LIST, FIXNUM, FLONUM, AND BIGNUM SPACES, AND TO
;;; **ONE** FOR SYMBOLS AND SARS. (THIS SPEEDS UP SWEEPING.)
;;; NEVER MARKS VALUE CELLS!!!! (THEY ARE NEVER SWEPT.)
;;; CALLED BY JSP T,GCMARK WITH OBJECT IN A. USES A,B,C,AR1,AR2A.
GCMARK: JUMPE A,(T) ;NEEDN'T MARK NIL
MOVEI AR2A,(P) ;REMEMBER WHERE P IS
GCMRK0: JRST GCMRK1 .SEE KLINIT
GCMRK3: TLNN A,GCBSYM ;MAYBE WE FOUND A SYMBOL
JRST GCMRK4 ;NOPE
HLRZ AR1,(C) ;YUP
TROE AR1,1
JRST GCMKND
HRLM AR1,(C)
PUSH P,(C) ;PUSH PROPERTY LIST
PUSH P,(AR1) ;PUSH PNAME LIST
SKIPE ETVCFLSP ;A HAC TO SAVE TIME IF THERE NEVER HAVE BEEN
JRST GCMRK6 ; VALUE CELLS TAKEN FROM LIST SPACE
HRRZ A,@-1(AR1)
JRST GCMRK1 ;GO MARK VALUE OF SYMBOL
GCMRK6: HRRZ A,-1(AR1)
CAIGE A,EVCSG
CAIGE A,BVCSG
JRST GCMRK7
HRRZ A,(A)
CAIE A,QUNBOUND
JRST GCMRK1
JRST GCMRK8
GCMRK7: LSH A,-SEGLOG
SKIPL A,GCST(A) ;SKIP IF VALUE CELL NOT A LIST CELL??
JRST GCMKND ;SUNBOUND, FOR EXAMPLE????
HRRZ A,-1(AR1) ;POINTING TO A VC IN LIST SPACE
JRST GCMRK1
GCMRK4: TLNN A,GCBVC ;MAYBE WE FOUND A VALUE CELL
JRST GCMRK5 ;NOPE
HRRZ A,(C) ;YUP - MARK ITS CDR (THE VALUE)
JRST GCMRK1
GCMRK5: MOVSI AR1,TTS<GC> ;MUST BE AN ARRAY
IORM AR1,TTSAR(C) ;SET ARRAY MARK BIT TO 1
GCMKND: CAIN AR2A,(P) ;SKIP IF ANYTHING LEFT ON STACK TO MARK
JRST (T) ;ELSE RETURN
GCMRK8: POP P,A ;GET NEXT ITEM TO MARK
GCMRK1: HRRZS C,A ;ZERO LEFT HALF OF A, ALSO SAVE IN C
SETZ B,
LSHC A,-SEGLOG ;GET PAGE NUMBER OF ITEM (OTHER BITS GO INTO B)
SKIPL A,GCST(A) ;CHECK GCST ENTRY FOR THAT PAGE
JRST GCMKND ;NOT MARKABLE - IGNORE IT
TLNE A,GCBFOO ;MAYBE IT'S A VALUE CELL OR SYMBOL OR SAR
JRST GCMRK3 ;IF SO HANDLE IT SPECIALLY
LSHC A,SEGLOG-5 ;THIS GETS ADDRESS OF BIT WORD FOR THIS ITEM
ROT B,5 ;B TELLS US WHICH BIT (40/WD)
MOVE AR1,(A) ;GET WORD OF MARK BITS
TDZN AR1,GCBT(B) ;CLEAR THE ONE PARTICULAR BIT
JRST GCMKND ;QUIT IF ITEM ALREADY MARKED
MOVEM AR1,(A) ;ELSE SAVE BACK WORD OF BITS
JUMPGE A,GCMKND .SEE GCBCDR ;JUMP UNLESS MUST MARK THROUGH (REMEMBER THE LSHC)
HRR A,(C) ;GET CDR OF ITEM
TLNN A,GCBCAR←<SEGLOG-5> ;MAYBE WE ALSO WANT TO MARK THE CAR
JRST GCMRK1 ;NO - GO MARK CDR
PUSH P,A ;YES - SAVE CDR ON STACK
HLR A,(C) ;GET CAR OF ITEM AND GO MARK IT
IFE HNKLOG, JRST GCMRK1
IFN HNKLOG,[
TLNN A,GCBHNK←<SEGLOG-5>
JRST GCMRK1 ;ORDINARY LIST CELL
PUSH P,T ;FOR HUNK, SAVE T AND AR2A SO
HRLM AR2A,(P) ; CAN CALL GCMARK RECURSIVELY
MOVEI A,(C)
LSH A,-SEGLOG
HRRZ A,ST(A) ;GET TYPEP OF HUNK
2DIF [HRL C,(A)]GCHNLN,QHUNK1 ;C NOW HAS AOBJN POINTER
MOVEI AR2A,(P) ;SET UP AR2A FOR RECURSIVE GCMARK
GCMRK2: MOVEM C,-1(P) ;SAVE AOBJN POINTER IN SLOT PUSHED FOR CDR
HLRZ A,(C)
JUMPE A,GCMK2A
JSP T,GCMRK1 ;MARK ODD HUNK SLOT
MOVE C,-1(P)
GCMK2A: HRRZ A,(C)
JUMPE A,GCMK2B
JSP T,GCMRK1 ;MARK EVEN HUNK SLOT
MOVE C,-1(P)
GCMK2B: AOBJN C,GCMRK2
POP P,T ;RESTORE T AND AR2A
HLRZ AR2A,T
SUB P,R70+1 ;FLUSH AOBJN POINTER
JRST GCMKND
GCHNLN:
REPEAT HNKLOG, -<2←.RPCNT> ;LH'S FOR AOBJN POINTERS
] ;END OF IFN HNKLOG
IFN ITS,[ IFE SEGLOG-11,[ IFLE HNKLOG-5,[
;;; MARK ROUTINE FOR USE WITH KL-10 MICROCODE
LSPGCM=070000,,
LSPGCS=071000,,
KLGCVC: SKIPA A,(A)
PUSH P,B
KLGCM1: LSPGCM A,KLGCM2
KLGCND: CAIN AR2A,(P)
JRST (T)
POP P,A
JRST KLGCM1
KLGCM2: JRST KLGCSY
JRST KLGCVC
JRST KLGCSA
REPEAT HNKLOG, JRST CONC KLGH,\.RPCNT+1
REPEAT 8-.+KLGCM2, .VALUE
KLGCSY: HLRZ AR1,(A)
TROE AR1,1
JRST KLGCND
HRLM AR1,(A)
PUSH P,(A)
PUSH P,(AR1)
HRRZ A,@-1(AR1)
JRST KLGCM1
KLGCSA: MOVSI AR1,TTS<GC>
IORM AR1,TTSAR(A)
JRST KLGCND
IFN HNKLOG,[
ZZZ==<1←HNKLOG>-1
REPEAT HNKLOG,[
CONC KLGH,\HNKLOG-.RPCNT,:
REPEAT 1←<HNKLOG-.RPCNT-1>,[
PUSH P,ZZZ(A)
HLRZ B,(P)
PUSH P,B
ZZZ==ZZZ-1
] ;END OF REPEAT 1←<HNKLOG-.RPCNT-1>
] ;END OF REPEAT HNKLOG
IFN ZZZ, WARN [YOU LOSE]
PUSH P,(A)
HLRZ A,(A)
JRST KLGCM1
] ;END OF IFN HNKLOG
KLGCSW: MOVNI T,3+BIGNUM ;SWEEP
KLGS1: SETZB C,AR1 ;ZERO FREELIST AND COUNT
SKIPN TT,FSSGLK+3+BIGNUM(T)
JRST KLGS1D
KLGS1A: MOVE B,GCST(TT)
LSH B,SEGLOG-5
TLZ B,-1
MOVEI A,(TT)
LSH A,SEGLOG
HRLI A,-SEGSIZ
LSPGCS A,1
LDB TT,[SEGBYT,,GCST(TT)]
JUMPN TT,KLGS1A
KLGS1D: MOVEM C,FFS+3+BIGNUM(T)
HRRM AR1,NFFS+3+BIGNUM(T)
AOJL T,KLGS1
JRST GCSW4A
]]] ;END OF IFLE HNKLOG-5, IFE SEGLOG-11, IFN ITS
GSGEN: SKIPN AR2A,GCMKL ;GENERATE TAILS OF GCMKL AND APPLY
POPJ P, ;FUN IN AR1 TO THEM
PUSH P,AR1
MOVEI AR1,GCMKL
JRST GGEN1
RTSPC2: JUMPE A,GGEN2
RTSP2A: ADD D,TT
GGEN2: HRRZ AR2A,(AR2A) ;GENERAL LOOP FOR GSGEN
MOVEI AR1,(AR2A)
HRRZ AR2A,(AR2A)
GGEN1: JUMPE AR2A,POP1J ;TAIL OF GCMKL IN AR2A,
HRRZ A,(AR2A) ;SPACE OCCUPIED IN TT,
HLRZ A,(A) ;ALIVEP IN A
MOVE TT,(A)
HLRZ A,(AR2A)
HLRZ A,ASAR(A)
JRST @(P) ;ROUTINE WILL RETURN TO GGEN2
GFSPC: PUSH FXP,AR1
PUSHJ P,CNLAC ;COUNT NUMBER OF LIVING ARRAY CELLS
POP FXP,AR1
ADD D,@VBPORG ;NOW HAS TOTAL AMOUNT FREE IN BPS [COUNTING DEAD BLOCKS]
ADD D,GAMNT ;NOW DIMINISHED BY REQUESTED AMOUNT
CAMG D,BPSH
JRST GRELAR ;IF ENOUGH SPACE, THEN RELOCATE
JRST (R)
;GTSP5:
;$$ POP FXP,AR1
GTSP5A: SETZB A,TT ;GIVE OUT NIL AND 0 IF FAIL
JUMPLE AR1,CZECHI
PUSHJ P,BPSGC
JSP R,GFSPC
SETZ AR1,
JRST GTSP1B
BPSGC: MOVEI R,444444 ;GC SPECIFICALLY FOR BPS
HRLM R,(P)
JRST AGC
;;; SOME ROUTINES FOR USE WITH GSGEN
GCP8K: HLRZ A,(D)
JSP T,GCMARK
GCP8J: HRRZ D,(D) ;MARK ATOMS ON OBLIST
GCP8I: JUMPE D,GCP8A ;WHICH HAVE NON-TRIVIAL
MOVE A,D ;P-LIST STRUCTURE.
JSP T,TWAP
JRST GCP8J
JRST GCP8K
JRST GCP8J
GCP8G: JUMPE D,GCP8A ;REMOVE T.W.A.'S FROM
MOVE A,D ;BUCKETS OF OBLIST.
JSP T,TWAP
JRST GCP8B
JRST GCP8B
HRRZ D,(D)
TLNE R,400000 ;BUCKET COMES FROM LH OF WORD IN OBARRAY
HRLM D,(F) ;IF AT THIS POINT R < 0
TLNN R,400000
HRRM D,(F)
JSP T,GCP8L
JRST GCP8G
GCP8C: HRRZ D,(D)
GCP8B: HRRZ A,(D)
GCP8D: JUMPE A,GCP8A
JSP T,TWAP
JRST GCP8C
JRST GCP8C
HRRZ A,(D)
HRRZ A,(A)
HRRM A,(D)
JSP T,GCP8L
JRST GCP8B
GCP8H: MOVE A,D ;MARK OBLIST BUCKET
JSP T,GCMARK
JRST GCP8A
GCP8L: JUMPE TT,(T) ;IF SCO REMOB'D, THEN REMOVE FROM SCO TABLE
HRRZ A,(TT)
JUMPN A,(T)
HLRZ A,(TT)
MOVE B,(A) ;MUST NOT BE INTERRUPTIBLE HERE
MOVEI A,0
LSHC A,7
JUMPN B,(T)
HRRZ TT,VOBARRAY
HRRZ TT,TTSAR(TT)
ADDI TT,<OBTSIZ+1>/2
ROT A,-1
ADD TT,A
JUMPL TT,GCP8L5
HRRZS (TT)
JRST (T)
GCP8L5: HLLZS (TT)
JRST (T)
TWAP: HLRZ A,(A)
JUMPE A,(T) ;NIL IS ALREADY MARKED
HLRZ TT,(A)
TRZE TT,1
JRST (T) ;NO SKIP IF ALREADY MARKED
MOVE B,(TT)
MOVE TT,1(TT)
TLNN B,300 ;SKIP 1 OF SYMBOL HAS SOME NON-TRIVIAL
TLZE TT,-1 ;PROPERTIES, E.G., ARGS OR COMPILED CODE REFERENCE
JRST 1(T)
HRRZ B,(B)
HRRZ A,(A)
CAIN B,QUNBOUND
JUMPE A,2(T) ;SKIP 2 IF TRULY WORTHLESS SYMBOL, I.E., UNBOUND AND NO PROPERITES
JRST 1(T) ;SKIP 1 IF MEANINGFUL PROPERTIES OR VALUE
;;; PRINT MESSAGE OF FORM "NNN[MM%] " FOR GC STATISTICS OUTPUT
STGPNT: PUSH FXP,T ;RECLAIMED AMNT IN T, TOTAL FOR SPACE IN TT
IMULI T,100.
IDIVM T,TT
EXCH TT,(FXP)
Q% MOVEI R,TYO
Q$ HRRZ AR1,VMSGFILES
Q$ TLO AR1,200000
Q$ MOVEI R,$TYO
IFE USELESS, MOVE C,@VBASE ;BASE HAD DAMNED WELL BETTER BE A FIXNUM
IFN USELESS,[
HRRZ C,VBASE
CAIE C,QROMAN
SKIPA C,(C)
PUSHJ P,PROMAN ;SKIPS
] ;END OF IFN USELESS
PUSHJ P,PRINI2
STRT 17,[SIXBIT \[!\] ;BEWARE THESE BRACKETS!!!!!
POP FXP,TT
IFE USELESS, MOVEI C,10.
IFN USELESS,[
HRRZ C,VBASE
CAIE C,QROMAN
SKIPA C,[10.]
PUSHJ P,PROMAN
] ;END OF IFN USELESS
PUSHJ P,PRINI3 ;EFFECTIVELY, PRINI2 WITH *NOPOINT=T
STRT 17,[SIXBIT \%] !\] ;BEWARE THESE BRACKETS!!!!!
POPJ P,
;;; VERY IMPORTANT TABLE OF WORDS WITH SINGLE BITS!!! USED FOR MARKING!!!
GCBT: REPEAT 36., SETZ←-.RPCNT
IFE D10,[
SUBTTL RETURN CORE TO TIMESHARING SYSTEM
;;; HAIRY ROUTINE TO DECIDE WHETHER TO RETURN SOME BPS TO THE SYSTEM.
;;; MAY ONLY BE CALLED WHEN NOQUIT SPECIFIES NO INTERRUPTS.
RETSP: MOVEI TT,4 ;GTSPC1 IS ALLOWED TO GRAB 4 PAGES
MOVEM TT,ARPGCT ; BEFORE INVOKING GC FOR LACK OF CORE
PUSHJ P,CNLAC ;COUNT NUMBER OF LIVING ARRAY CELLS
MOVE TT,BPSH
LSH TT,-PAGLOG ;CURRENT HIGHEST CORE BLOCK IN BPS
MOVE R,@VBPORG
ADDI R,1(D)
LSH R,-PAGLOG ;CORE NEEDED IF ARRAYS WERE PACKED
CAML R,TT
POPJ P,
LSH R,PAGLOG
ADDI R,PAGSIZ-1
HRLM R,RTSP1 ;NEW BPSH
SUB R,D
HRRM R,RTSP3 ;NEW BPEND.
JUMPE D,RTSP5
HRLM D,RTSP3 ;NO. OF CELLS TO MOVE.
PUSHJ P,GRELAR ;(LEAVES BPEND-AFTER-RELOCATION IN TT.)
HRL AR1,TT
HRR AR1,RTSP3 ;BLOCK PTR.
SUBI TT,(AR1)
JUMPLE TT,RTSP2
MOVNI TT,1(TT)
HRRM TT,RTSP1
ADD AR1,R70+1
HLRZ C,RTSP3
ADD C,RTSP3
BLT AR1,(C)
MOVEI AR1,RTSPC1
PUSHJ P,GSGEN ;DO PATCH-UP ON ARRAY PARAMETERS
JSP T,RSXST ;????
RTSP2: HLRZ TT,RTSP1
MOVE R,TT
EXCH R,BPSH
HRRZ D,RTSP3
MOVEM D,@VBPEND
IFE D10,[
LSH R,-PAGLOG ;OLD CORE HIGHEST
LSH TT,-PAGLOG ;NEW CORE HIGHEST
SUBI R,(TT)
MOVEI F,1(TT)
ROT F,-4
ADDI F,(F)
ROT F,-1
TLC F,770000
ADD F,[450200,,PURTBL]
MOVEI D,1(TT)
LSH D,-SEGLOG+PAGLOG
MOVE T,[$NXM,,QRANDOM]
SETZ AR1,
LSH TT,11
RTSP7: ADDI TT,1000
.CBLK TT,
POPJ P,
TLNN F,730000
TLZ F,770000
IDPB AR1,F
REPEAT SGS%PG, MOVEM T,ST+.RPCNT(D)
ADDI D,SGS%PG
SOJG R,RTSP7
] ;END OF IFE D10
10$ CORE TT,
10$ LERR [SIXBIT \CORE?!\]
POPJ P,
RTSP5: SETZM GCMKL ;NO ARRAYS ALIVE
MOVE TT,R
PUSHJ P,BPNDST ;SETQ UP BPEND
JRST RTSP2
RTSPC1: JUMPE A,GGEN2
HRRE B,RTSP1 ;-(SIZE OF SHIFT + 1).
JSP AR1,GT3D
JRST GGEN2
] ;END OF IFE D10
SUBTTL GET SPACE FROM TIMESHARING SYSTEM
GTSPC1: HLLOS NOQUIT
JSP R,GFSPC ;SEE IF FREE SPACE ABOVE BPEND WILL ADD ENOUGH
SKIPLE AR1,ARPGCT
JRST GTSP1B
PUSHJ P,BPSGC ;WHEN COMPACTIFIED AND RELOCATED
JSP R,GFSPC ;IF NOT, GC AND TRY AGAIN
GTSP1B:
IFE D10,[
CAML D,HINXM
JRST GTSP5A
MOVEI T,(D)
TRO T,PAGSIZ-1
MOVE R,BPSH
LSH D,-PAGLOG
LSH R,-PAGLOG
SUB D,R
MOVN F,D
ADDM F,ARPGCT
MOVEI F,1(R)
ROT F,-4
ADDI F,(F)
ROT F,-1
TLC F,770000
ADD F,[450200,,PURTBL]
MOVEI TT,1(R)
LSH TT,-SEGLOG+PAGLOG
MOVE A,[$XM,,QRANDOM]
PUSH FXP,AR1
HLRZ AR1,(P) ;BEWARE! LH OF CALLING PDL SLOT = -1
TRNN AR1,1 ; MEANS THE GETSP FUNCTION IS CALLING
TROA AR1,3
MOVEI AR1,1
LSH R,11
IOR R,[004400,,400000]
GTSPC2: ADDI R,1000
.CBLK R,
; JRST GTSP5 ;FAILURE GIVES OUT NIL IN A, 0 IN TT
.LOSE 1000+%ENACR ;NO CORE AVAILABLE - TELL DDT
TLNN F,730000
TLZ F,770000
IDPB AR1,F
REPEAT SGS%PG, MOVEM A,ST+.RPCNT(TT)
ADDI TT,SGS%PG
SOJG D,GTSPC2
POP FXP,AR1
MOVEM T,BPSH ;FALLS INTO GRELAR
] ;END OF IFE D10
IFN D10,[
SETZB A,TT ;GIVE OUT NIL AND 0 IF WE FAIL
JRST CZECHI
] ;END OF IFN D10
GRELAR: HLLOS NOQUIT ;MOBY DELAYED QUIT FEATURE.
HRRZ A,BPSH ;LEAVE BPEND-AFTER-RELOCATION AS RESULT
MOVEM A,GSBPN ;TEMPORARY BPEND
MOVEI AR1,GTSPC3
PUSHJ P,GSGEN ;RELOCATE ARRAYS
JSP T,RSXST
GREL1: MOVE TT,GSBPN
PUSHJ P,BPNDST
MOVE TT,(A)
CZECHI: HLLZS NOQUIT
JRST CHECKI ;CHECK FOR ↑G THEN POPJ P,
SUBTTL ARRAY RELOCATOR
CNLAC: MOVEI D,0 ;COUNT NUMBER OF LIVING ARRAY CELLS, IN D
MOVEI AR1,RTSPC2
JRST GSGEN
BPNDST: JSP T,FIX1A ;STORE NEW VALUE FOR BPEND
MOVEM A,VBPEND
POPJ P,
;;; COMES HERE FROM GRELAR VIA GSGEN. AR2A HAS TAIL OF GCMKL, TT HAS TOTAL LENGTH OF ARRAY
GTSPC3: JUMPE A,GT3G ;RELOCATE AN ARRAY
MOVEI AR1,-1(TT) ;LENGTH-1 OF ARRAY IN AR1
HLRZ A,(AR2A)
HRRZ A,ASAR(A)
SUBI A,1 ;ARRAY AOBJN PTR LOC IN A.
MOVE C,GSBPN
SUBI C,(AR1)
MOVEM C,GSBPN ;LOC NEW BPTR IN C
MOVEI B,(C)
SUBI B,1(A) ;RELOCATION AMOUNT-1 IN B
CAML A,C ;IS ARRAY ALREADY IN PLACE?
JRST GT3C ;YES, SO EXIT
SUBI C,(AR1)
CAMGE A,C ;BEWARE: C COULD GO NEGATIVE!
JRST GT3A ;GOOD, EASY BLT
ADDI C,(AR1)
ADDI AR1,1(A) ;FIRST DESTINATION LOC
GT3B: HRRZI C,(AR1)
SUBI AR1,1(B) ;CONSTRUCT SOURCE ADDRESS
HRLI C,(AR1)
HRRZI T,(C)
ADDI T,(B)
BLT C,(T) ;SERIES OF SMALL BLTS
CAMLE AR1,GSBPN
JRST GT3B
ADDI AR1,(B)
SUB AR1,GSBPN
MOVE A,GSBPN
SUBI A,1(B)
GT3A: MOVE C,GSBPN
ADDI AR1,(C)
HRL C,A
BLT C,(AR1) ;FINAL (OR ONLY) BLT
JSP AR1,GT3D
GT3C: SOS GSBPN
JRST GGEN2
GT3D: ADDI B,1
HLRZ A,(AR2A)
ADDM B,ASAR(A) ;UPDATE ARRAY POINTERS BY OFFSET IN B
ADDM B,TTSAR(A)
MOVE C,ASAR(A)
ADDM B,-1(C) ;UPDATE AOBJN PTR BEFORE ARRAY HEADER
Q% JRST (AR1)
IFN QIO,[
HRR C,TTSAR(A)
TLNE C,AS<FIL>
SKIPGE F.MODE(C)
JRST (AR1)
MOVE C,TTSAR(A)
10% ADDM B,AB.BP(C) .SEE XB.AOB
10% ADDM B,FB.IOT(C)
10$ ADDM B,FB.NBF(C)
JRST (AR1)
] ;END OF IFN QIO
GT3G: HRRZ AR2A,(AR2A)
HRRZ AR2A,(AR2A)
HRRM AR2A,(AR1) ;CUT OUT DEAD BLOCK
JRST GGEN1
PGTOP GC,[GARBAGE COLLECTOR]
;;; ********** MEMORY MANAGEMENT, ETC **********
SUBTTL PURCOPY FUNCTION
PGBOT BIB
PURCOPY: PUSHJ FXP,SAV5M2
PUSH P,[RST5M2]
PUSH FXP,CCPOPJ
PUSHJ P,SAVX5
PUSH P,[RSTX5]
MOVEI TT,(A) ;USES A,B,T,TT
LSH TT,-SEGLOG
MOVE TT,ST(TT)
TLNE TT,PUR
POPJ P,
2DIF JRST (TT),PCOPY9,QLIST .SEE STDISP
PCOPY9: JRST PCOPLS ;LIST
JRST PCOPFX ;FIXNUM
JRST PCOPFL ;FLONUM
DB$ JRST PCOPDB ;DOUBLE
CX$ JRST PCOPCX ;COMPLEX
DX$ JRST PCOPDX ;DUPLEX
BG$ JRST PCOPBN ;BIGNUM
JRST PCOPSY ;SYMBOL
REPEAT HNKLOG, JRST PCOPHN ;HUNKS
POPJ P, ;RANDOM
MOVSI TT,100 ;ARRAY
IFN .-PCOPY9-NTYPES, WARN [WRONG LENGTH TABLE]
IORM TT,(A) ;SET "COMPILED CODE NEEDS ME" BIT
POPJ P,
PCOPLS: HLRZ B,(A) ;PURCOPY A LIST ALREADY
PUSH P,B
HRRZ A,(A)
PUSHJ P,PURCOPY
EXCH A,(P)
PUSHJ P,PURCOPY
POP P,B
PCONS: AOSL TT,NPFFS ;PURE FS CONSER
SPECPRO INTPPC
PUSHJ P,GTNPSG ;NOTE: CLOBBERS TT
ADD TT,EPFFS
NOPRO
HRLM A,(TT)
HRRM B,(TT)
MOVEI A,(TT)
POPJ P,
PCOPFX: MOVE TT,(A)
PFXCONS: CAIGE TT,XHINUM ;PURE FIXNUM CONSER
CAMGE TT,[-XLONUM]
JRST PFXC1
MOVEI A,IN0(TT)
POPJ P, ;NOTE: EXITS WITH POPJ P,!!!
PFXC1: AOSL A,NPFFX
SPECPRO INTPPC
PUSHJ P,GTNPSG
ADD A,EPFFX
NOPRO
PFXC3: MOVEM TT,(A)
POPJ P,
PCOPFL: MOVE TT,(A)
PFLCONS: AOSL A,NPFFL ;PURE FLONUM CONSER
SPECPRO INTPPC
PUSHJ P,GTNPSG
ADD A,EPFFL
NOPRO
JRST PFXC3 ;ALSO EXITS WITH POPJ P,!!!
IFN CXFLAG,[
PCOPCX:
KA MOVE D,1(A)
KA MOVE TT,(A)
KIKL DMOVE TT,(A)
PCXCONS: AOSL A,NPFFC
SPECPRO INTPPC
PUSHJ P,GTNPSG
XCTPRO
MOVEI T,1(A)
MOVEM T,NPFFC
ADD A,EPFFC
NOPRO
DB% JRST PDBC3 ;WILL DROP IN IF NO DOUBLES
] ;END OF IFN CXFLAG
IFN DBFLAG,[
PCOPDB:
KA MOVE D,1(A)
KA MOVE TT,(A)
KIKL DMOVE TT,(A)
PDBCONS: AOSL A,NPFFD
SPECPRO INTPPC
PUSHJ P,GTNPSG
XCTPRO
MOVEI T,1(A)
MOVEM T,NPFFD
ADD A,EPFFD
NOPRO
] ;END OF IFN DBFLAG
IFN DBFLAG+CXFLAG,[
PDBC3:
KA MOVEM D,1(A)
KA JRST PFXC3
KIKL DMOVEM TT,(A)
KIKL POPJ P,
] ;END OF IFN DBFLAG+CXFLAG
IFN DXFLAG,[
PCOPDX:
KA REPEAT 4, MOVE TT+<2#.RPCNT>,.RPCNT
KIKL DMOVE R,(A)
KIKL DMOVE TT,2(A)
PDXCONS: AOSL A,NPFFZ
SPECPRO INTPPC
PUSHJ P,GTNPSG
XCTPRO
MOVEI T,3(A)
MOVEM T,NPFFZ
ADD A,EPFFZ
NOPRO
KA REPEAT 4, MOVEM TT+<2#.RPCNT>,.RPCNT
KIKL DMOVEM R,(A)
KIKL DMOVEM TT,2(A)
POPJ P,
] ;END OF IFN DBFLAG
IFN BIGNUM,[
PCOPBN: PUSH P,(A)
HRRZ A,(A)
PUSHJ P,PURCOPY
HLL A,(P)
SUB P,R70+1
PBNCONS: AOSL TT,NPFFB ;PURE BIGNUM CONSER
SPECPRO INTPPC
PUSHJ P,GTNPSG
ADD TT,EPFFB
NOPRO
MOVEM A,(TT)
MOVEI A,(TT)
POPJ P,
] ;END OF IFN BIGNUM
PCOPSY: PUSH P,A
HLRZ B,(A)
MOVE TT,(B)
TLNE TT,200
JRST PCOPS1
PUSH P,B
HRRZ A,1(B)
PUSHJ P,PURCOPY
POP P,B
HRRM A,1(B)
MOVSI TT,100
IORM TT,(B)
PCOPS1: LOCKI
JSP TT,ATMHSH
IDIVI T,OBTSIZ
PUSH FXP,TT
MOVEI A,(FXP)
MOVE T,VOBARRAY
PUSHJ P,@ASAR(T)
MOVEI B,(A)
HRRZ A,(P)
PUSHJ P,MEMQ
POP FXP,D
JUMPN A,PCOPS3
MOVEI T,1 ;GCPROTECT
HRRZ A,(P)
PUSHJ P,.GCPRO
PCOPS3: UNLOCKI
JRST POPAJ
IFN HNKLOG,[
PCOPHN: SKIPN VHUNKP ;TREAT HUNKS AS LISTS IF HUNKP IS NIL
JRST PCOPLS
2DIF [HRRZ B,(TT)]GCWORN,QLIST
PUSH P,B .SEE INTXCT ;CAN'T USE FXP
2DIF [AOSL B,(TT)]NPFFS,QLIST
2DIF [SKIPL (TT)]NPFFS,QLIST ;THIS WORD ALSO SERVES AS ARGUMENT TO GTNPSG!
SPECPRO INTPPC
PUSHJ P,GTNPSG
XCTPRO
MOVEI D,-1(B)
ADD D,(P)
2DIF [MOVEM D,(TT)]NPFFS,QLIST
NOPRO
2DIF [ADD B,(TT)]EPFFS,QLIST ;B NOW HAS ADDRESS OF FRESH PURE HUNK
PUSH P,A
PUSH P,B
MOVE D,(P)
PCOPH3: ADD D,-1(P) ;WE SCAN THE OLD HUNK FROM THE END BACKWARDS
HLRZ B,-1(D) ;GOBBLE A CAR AND A CDR
HRRZ A,-1(D)
PUSH P,B
PUSHJ P,PURCOPY ;PURCOPY THE CDR
EXCH A,(P)
PUSHJ P,PURCOPY ;PURCOPY THE CAR
HRLM A,(P)
MOVE D,(P) ;CALCULATE PLACE IN NEW HUNK
ADD D,-1(P)
POP P,-1(D) ;POP COPIED CAR/CDR PAIR INTO PURE HUNK
SOSE D,(P)
JRST PCOPH3
SUB P,R70+3
POPJ P,
] ;END OF IFN HNKLOG
IFN ITS,[
SUBTTL GETCOR
;;; THIS ROUTINE IS SPECIFICALLY FOR PEOPLE WHO HAND-CODE LAP.
;;; IT IS USED TO ALLOCATE A NUMBER OF CONSECUTIVE PAGES
;;; OF MEMORY FOR VARIOUS PURPOSES, E.G. HACKING OF PDP-11'S
;;; OR INFERIOR JOBS OR WHATEVER.
;;; THE NUMBER OF PAGES DESIRED SHOULD BE IN TT; THE LOW ADDRESS
;;; OF THE PAGES IS RETURNED IN TT, OR ZERO FOR FAILURE.
;;; THIS ROUTINE DOES NOT ACTUALLY GET CORE; IT MERELY RESERVES
;;; ADDRESS SPACE.
;;; THERE IS CURRENTLY NO PROVISION FOR RETURNING THE MEMORY GRABBED.
GETCOR: HLLOS NOQUIT
LSH TT,PAGLOG
MOVE T,HINXM
SUBI T,(TT)
CAMGE T,BPSH
JRST GTCOR6
MOVEI F,(TT) ;GETTING F THIS WAY FLUSHES
LSH F,-PAGLOG ; RANDOM BITS. (IT'S SAFER.)
GTCOR4: JSP R,ALIMPG
.VALUE ;HOW CAN WE LOSE HERE?
SOJG F,GTCOR4
SKIPA TT,HINXM
GTCOR6: TDZA TT,TT ;LOSE, LOSE, LOSE
ADDI TT,1
JRST CZECHI
IFN LHFLAG,[
LHVB0: WTA [BAD SIZE - LH↑<!]
LHVBAR: CAIL B,QLIST ;SUBR 2
CAILE B,QARRAY ;GROSS KLUDGE FOR LH
JRST LHVB1
JSP T,FXNV1
TLNE TT,-1
JRST LHVB0
ADDI TT,PAGSIZ-1
IDIVI TT,PAGSIZ
MOVNI AR2A,(TT)
PUSHJ P,GETCOR
JUMPE TT,FIX1
CAIE B,QARRAY
CAIN B,QRANDOM
XORI B,QARRAY#QRANDOM ;GROSS KLUDGE
MOVEI D,(TT)
LSH D,-SEGLOG
IMULI AR2A,SGS%PG
HRLI D,(AR2A)
2DIF [MOVE R,(B)]GCWORS,QLIST
LHVB3: MOVEM R,ST(D)
SETZM GCST(D)
TLNN R,$FS+BN+HNK
JRST LHVB4
MOVE T,LHSGLK
DPB T,[SEGBYT,,GCST(D)]
HRRZM D,LHSGLK
LHVB4: AOBJN D,LHVB3
JRST FIX1
LHVB1: EXCH A,B
WTA [BAD SPACE - LH↑<!]
EXCH A,B
JRST LHVBAR
] ;END OF IFN LHFLAG
;;; IFN ITS
SUBTTL PDL OVERFLOW HANDLER
;PDLSTH: 0 ;HACK ST FOR ADDING PDL PAGES
PDLST0: MOVEI R,(D) ;USED BY PDLHAK TO EXTEND PDLS
LSH R,11-PAGLOG ;D HAS BASE ADDRESS OF PAGE DESIRED
IOR R,[4400,,400000] ;USES ONLY D AND R
.CBLK R, ;CAUSE NEW PDL PAGE TO EXIST
.LOSE 1000+%ENACR ;NO CORE AVAILABLE
MOVEI R,(D) ;CALCULATE PURTBL BYTE POINTER
ROT R,-PAGLOG-4
ADDI R,(R)
ROT R,-1
TLC R,770000
ADD R,[430200,,PURTBL]
MOVEM P,FAKFXP ;SAVE P AT BOTTOM OF FAKE FXPDL
MOVEI P,3
DPB P,R ;UPDATE PURTBL
LSH D,-SEGLOG ;HORRIBLE HACKERY TO UPDATE ST
ADD D,[-SGS%PG-1,,ST-1] ; WITHOUT AN EXTRA AC:
Q% REPEAT SGS%PG, PUSH D,PDLST9-P(A) ; USE PUSHES! (CAN'T OVERFLOW)
Q$ REPEAT SGS%PG, PUSH D,PDLST9-P(F) ; USE PUSHES! (CAN'T OVERFLOW)
MOVE P,FAKFXP
JRST @PDLSTH
;;; IFN ITS
IFE QIO,[
;PDLHAK: 0 ;CALLED WHEN SOME PDL OVERFLOWS
PDLH0: MOVEM D,QITD ;A=0 => CAUSED BY PUSH OR PUSHJ, ELSE
MOVEM R,QITR ; UINT0 GIVES <# SLOTS NEEDED,,PDL AC>
JUMPN A,PDLH0A ;SO JUMP IF WE KNOW WHICH ONE
MOVEI A,P ;ALL RIGHT THEN, LET'S PLAY
JUMPGE P,PDLH0A ; TWENTY QUESTIONS - IS IT REGPDL?
MOVEI A,SP
JUMPGE SP,PDLH0A ;SPECPDL?
MOVEI A,FXP
JUMPGE FXP,PDLH0A ;FXP?
MOVEI A,FLP ;IF NOT FLP, THEN USER HAS LOST!
JUMPL FLP,[LERR [SIXBIT \USER PDL OVERFLOW!\]]
; JUMPGE FLP,PDLH0A
;IRP Z,,[P,FLP,FXP,SP]
; MOVES (Z) ;CROCK DUE TO ITS LOSSAGE
;TERMIN
; JRST PDLH3
PDLH0A: HRRZ R,(A) ;FETCH RIGHT HALF OF PDL POINTER
MOVEI D,(R)
CAML R,OC2-P(A) ;IF WE'RE OVER THE ORIGIN OF THE
JRST PDLH5 ; OVERFLOW PDL, THEN ERROR OUT
HLRZ R,A
ADDI R,11(D) ;HERE IS A HACK TO PAGIFY
IORI R,PAGSIZ-1 ; UPWARDS, BUT KEEP WELL AWAY
SUBI R,10 ; FROM THE PAGE BOUNDARY
CAML R,OC2-P(A) ;IF WE'RE ABOVE THE OVERFLOW PDL,
MOVE R,OC2-P(A) ; ONLY INCREASE TO THAT PLACE
CAMGE D,ZPDL-P(A) ;SKIP IF WE'RE ABOVE PDLMAX
JRST PDLH2 ; PARAMETER FOR THIS PDL
TLO A,-1 ;SET FLAG TO INDICATE THIS FACT
MOVE D,MORPDL-P(A) ;PUSH UP THE PDLMAX
ADD D,ZPDL-P(A) ; "SOME MORE"
ANDI D,777760 ;BUT KEEP AWAY FROM PAGE
TRNN D,PAGKSM ; BOUNDARY (PICKY, PICKY!)
SUBI D,20
MOVEM D,ZPDL-P(A)
HRRZ D,(A)
JRST PDLH2A
PDLH2: TLZE A,-1
JRST PDLH2B
CAMLE R,ZPDL-P(A) ;IF OUR GUESS WOULD PUT US OVER
PDLH2A: MOVE R,ZPDL-P(A) ; PDLMAX, GO ONLY AS FAR AS THAT
PDLH2B: SUBI D,(R) ;CALCULATE NEW LEFT HALF FOR PDL PTR
HRLM D,(A) ;CLOBBER INTO PDL PTR
HRRZ D,(A) ;FIGURE OUT IF WE NEED TOP GET
ADDI R,10 ; MORE CORE FOR ALL THIS
ANDI R,PAGMSK
EXCH R,D
CAIG R,(D) ;SKIP IF WE CROSSED NO PAGE BOUNDARY
JSR PDLSTH ;ELSE MUST GET NEW PAGE AND UPDATE ST
TLZN A,-1 ;SKIP IF WE WERE ABOVE PDLMAX
JRST PDLH3
HRLI A,QREGPDL-P(A)
HRRI A,12. ;STACK UP USER INT 12. (PDL-OVERFLOW)
HRRZ D,PDLHAK ;CAN STACK IT BECAUSE WE'RE IN UINT,
CAIN D,PDLOV3+1 ; WHICH WILL DO A CHECKI
JRST PDLH4
MOVE D,QITD ;RESTORE D AND R SO UISTAK
MOVE R,QITR ; CAN SAVE THEM AGAIN
JSR UISTAK
PDLH3: SETZ A,
PDLH4: MOVE D,QITD ;A NON-ZERO MEANS WE WANT TO RUN
MOVE R,QITR ; A PDL-OVERFLOW INT
JRST @PDLHAK
] ;END OF IFE QIO
;;; IFN ITS
IFN QIO,[
;;; HAIRY PDL OVERFLOW HANDLER
PDLOV: MOVE F,INTPDL
MOVEM D,IPSWD2(F) ;SAVE D
MOVEM R,IPSWD1(F) ;SAVE R
SKIPL INTPDL
.VALUE ;I WANT TO SEE THIS! - GLS
MOVEI F,P ;ALL RIGHT THEN, LET'S PLAY
JUMPGE P,PDLH0A ; TWENTY QUESTIONS - IS IT REGPDL?
MOVEI F,SP
JUMPGE SP,PDLH0A ;SPECPDL?
MOVEI F,FXP
JUMPGE FXP,PDLH0A ;FXP?
MOVEI F,FLP ;IF NOT FLP, THEN IT'S PRETTY RANDOM
JUMPGE FLP,PDLH0A
HLRZ R,NOQUIT
JUMPN R,PDLH3A
LERR [SIXBIT \RANDOM PDL OVERFLOW!\]
PDLH0A: HRRZ R,(F) ;FETCH RIGHT HALF OF PDL POINTER
MOVEI D,(R)
CAML R,OC2-P(F) ;IF WE'RE OVER THE ORIGIN OF THE
JRST PDLH5 ; OVERFLOW PDL, THEN ERROR OUT
HLRZ R,F
ADDI R,11(D) ;HERE IS A HACK TO PAGIFY
IORI R,PAGSIZ-1 ; UPWARDS, BUT KEEP WELL AWAY
SUBI R,10 ; FROM THE PAGE BOUNDARY
CAML R,OC2-P(F) ;IF WE'RE ABOVE THE OVERFLOW PDL,
MOVE R,OC2-P(F) ; ONLY INCREASE TO THAT PLACE
CAMGE D,ZPDL-P(F) ;SKIP IF WE'RE ABOVE PDLMAX
JRST PDLH2 ; PARAMETER FOR THIS PDL
TLO F,-1 ;SET FLAG TO INDICATE THIS FACT
MOVE D,MORPDL-P(F) ;PUSH UP THE PDLMAX
ADD D,ZPDL-P(F) ; "SOME MORE"
ANDI D,777760 ;BUT KEEP AWAY FROM PAGE
TRNN D,PAGKSM ; BOUNDARY (PICKY, PICKY!)
SUBI D,20
MOVEM D,ZPDL-P(F)
HRRZ D,(F)
JRST PDLH2A
PDLH2: TLZE F,-1
JRST PDLH2B
CAMLE R,ZPDL-P(F) ;IF OUR GUESS WOULD PUT US OVER
PDLH2A: MOVE R,ZPDL-P(F) ; PDLMAX, GO ONLY AS FAR AS THAT
PDLH2B: SUBI D,(R) ;CALCULATE NEW LEFT HALF FOR PDL PTR
HRLM D,(F) ;CLOBBER INTO PDL PTR
HRRZ D,(F) ;FIGURE OUT IF WE NEED TOP GET
ADDI R,10 ; MORE CORE FOR ALL THIS
ANDI R,PAGMSK
EXCH R,D
CAIG R,(D) ;SKIP IF WE CROSSED NO PAGE BOUNDARY
JSR PDLSTH ;ELSE MUST GET NEW PAGE AND UPDATE ST
TLZN F,-1 ;SKIP IF WE WERE ABOVE PDLMAX
JRST PDLH3A
MOVSI D,QREGPDL-P(F)
HRRI D,1005 ;PDL-OVERFLOW
HRRZ R,INTPDL
HRRZ R,IPSPC(R)
CAIL R,UINT0 ;AVOID DEEP INTERRUPT RECURSION:
CAILE R,EUINT0 ; IF PDL OVERFLOWED WITHIN UINT0,
JRST PDLH4 ; THEN JUST STACK UP THE INTERRUPT,
JSR UISTAK ; AND SOMEONE WILL EVENTUALLY TRY CHECKI
PDLH3A: HRRZ F,INTPDL
JRST INTXIT+1
PDLH4: MOVE R,FXP ;ELSE TRY TO GIVE A PDL OVERFLOW
SKIPE GCFXP ; USER INTERRUPT IMMEDIATELY
MOVE FXP,GCFXP ;REMEMBER, PDL OVERFLOW IS NOT
PUSH FXP,R ; DISABLED INSIDE THE PDL
PUSHJ FXP,IWAIT ; OVERFLOW HANDLER!!!
PUSHJ P,UINT
HRRZ F,INTPDL ;RESTORE THE WORLD
JRST INTXIT
] ;END OF IFN QIO
;;; IFN ITS
IFE QIO,[
PDLOV: .SUSET [.SIPIRQC,,A]
SETZ A, ;MEANS WE DON'T KNOW WHICH PDL YET
PDLOV3: JSR PDLHAK ;FIGURE IT OUT
JUMPE A,INTEX1
MOVEM A,CNTROL ;THIS IS A HACK
MOVEI A,INTEX1
EXCH A,CNTROL
JRST UINT1R ;GO RUN PDL-OVERFLOW INTERRUPT
] ;END OF IFE QIO
MORPDL: 400 ;AMOUNTS TO INCREMENT PDLS BY
100 ; WHEN OVERFLOW OCCURS (THIS GIVES
LSWS+100 ; LOSER A CHANCE TO SSTATUS PDLMAX,
200 ; AT LEAST)
PDLMSG: POVPDL ;REG
POVFLP ;FLONUM
POVFXP ;FIXNUM
POVSPDL ;SPEC
PDLST9: $XM,,QRANDOM ;TYPICAL ST ENTRIES FOR PDL PAGES
FL+$PDLNM,,QFLONUM
FX+$PDLNM,,QFIXNUM
$XM,,QRANDOM
PDLH5: IORI R,PAGSIZ-1 ;BAD PDL OV - REALLY DESPERATE
SUBI D,-2(R) ;GIVE US AS MUCH PDL AS IS LEFT
JUMPL D,PDLH6
MOVE P,C2
MOVE FXP,FXC2
SETZM TTYOFF
STRT UNRECOV
Q% STRT @PDLMSG-P(A)
Q$ STRT @PDLMSG-P(F)
JRST DIE
PDLH6:
Q% HRLM D,(A)
Q$ HRLM D,(F)
HLRZ R,NOQUIT
JUMPN R,GCPDLOV ;FOO! HAPPENED IN GC - BOMB OUT!
Q% HRRZ B,PDLMSG-P(A)
Q$ HRRZ B,PDLMSG-P(F)
CAIE B,POVSPDL
JRST PDLOV5 ;PDLOV5 HANDLE WILL GET US TO TOP LEVEL
MOVEM P,F ;FOR SP, TRY TO POP BINDINGS FIRST
HRRZ TT,SPSV ; SO *RSET-TRAP WON'T OVERFLOW
MOVE P,[-LFAKP-1,,FAKP] ;SO WE HAVE ENOUGH PDL FOR UBD
PUSH P,FXP
MOVE FXP,[-LFAKFXP-1,,FAKFXP]
PUSHJ P,UBD
POP P,FXP
MOVE P,F
JRST PDLOV5 ;PDLOV5 WILL SET UP PDLS
] ;END OF IFN ITS
SUBTTL PURE SEGMENT CONSER
;;; GTNPSG IS INVOKED AS FOLLOWS:
;;; AOSL A,NPFF% ;SKIP UNLESS NO MORE LEFT
;;; SPECPRO INTPPC
;;; PUSHJ P,GTNPSG ;MUST GET MORE
;;; ADD A,EPFF% ;ELSE JUST FIGURE OUT ABSOLUTE ADDRESS
;;; NOPRO
;;; WHERE % IS SOME APPROPRIATE LETTER (E.G. S, X, L, B).
;;; GTNPSG UPDATES NPFF% AND EPFF% BY LOOKING AT THE AOSL, THEN
;;; RETURNS TO THE AOSL.
XCTPRO
GTNPSG: HLLOS NOQUIT ;GET NEW PURE SEGMENT
NOPRO
REPEAT 2, SOS (P) ;BACK UP RETURN ADDRESS TO PRECEDING INST
SAVEFX T TT D
GTNPS1: MOVEI T,-SEGSIZ ;*NOT* "MOVNI T,SEGSIZ" !!!
ADDB T,PSGAOB ;INCR'S LH BY 1, DECR'S RH BY SEGSIZ
JUMPGE T,GTNPS3 ;FOO! MUST GRAB A NEW PAGE!
TLZ T,-1
LSH T,-SEGLOG
IFE HNKLOG, MOVE D,@(P) ;D POINTS TO NPFF-
IFN HNKLOG,[
MOVE D,(P) ;THIS ALLOWS REFERENCE TO NPFF- TO BE INDEXED
MOVEI D,@(D) ; BY TT, WHICH MUST BE SAFE TO THIS POINT
] ;END OF IFN HNKLOG
SKIPN TT,GTNPS8-NPFFS(D)
.VALUE
MOVEM TT,ST(T)
SETZM GCST(T)
LSH T,SEGLOG
ADDI T,SEGSIZ
MOVEM T,EPFFS-NPFFS(D) ;UPDATE PARAMETERS FOR NEW PURE SEGMENT
MOVNI T,SEGSIZ+1
MOVEM T,(D)
MOVEI T,SEGSIZ
ADDM T,PFSSIZ-NPFFS(D) ;UPDATE STORAGE SIZE
RSTRFX D TT T
JRST CZECHI
;;; TYPICAL ST ENTRIES FOR PURE SEGMENTS
GTNPS8: LS+$FS+PUR,,QLIST ;LIST
FX+PUR,,QFIXNUM ;FIXNUM
FL+PUR,,QFLONUM ;FLONUM
DB$ DB+PUR,,QDOUBLE ;DOUBLE
CX$ CX+PUR,,QCOMPLEX ;COMPLEX
DX$ DX+PUR,,QDUPLEX ;DUPLEX
BG$ BN+PUR,,QBIGNUM ;BIGNUM
0 ;NO PURE SYMBOLS
REPEAT HNKLOG, HNK+PUR,,QHUNK1+.RPCNT ;HUNKS
0 ;NO PURE SARS
IFN .-GTNPS8-NFF, WARN [GTNPS8 WRONG LENGTH TABLE]
$XM+PUR,,QRANDOM ;SYMBOL BLOCKS
GTNPS3:
IFE D10,[
MOVE T,HINXM ;FIGURE OUT IF ANY ROOM LEFT
SUBI T,PAGSIZ
CAMGE T,BPSH
] ;END OF IFE D10
IFN D10,[
MOVE TT,HIXM
ADDI TT,PAGSIZ
CAMLE TT,MAXNXM
] ;END OF IFN D10
LERR [SIXBIT \NO SPACE FOR NEW PURE PAGE!\]
IFE D10,[
AOS TT,HINXM
MOVEM T,HINXM ;UPDATE HINXM
HRLI TT,-SGS%PG-1
MOVEM TT,PSGAOB ;UPDATE AOBJN PTR
MOVEI TT,1(T)
] ;END OF IFE D10
IFN D10,[
MOVEM TT,HIXM
HRLI TT,-SGS%PG-1
MOVEM TT,PSGAOB
AOS PSGAOB
TLZ TT,-1
] ;END OF IFN D10
LSH TT,-SEGLOG ;UPDATE ST AND GCST FOR NEW PAGE
MOVE D,[$XM+PUR,,QRANDOM]
REPEAT SGS%PG, MOVEM D,ST+.RPCNT(TT)
REPEAT SGS%PG, SETZM GCST+.RPCNT(TT)
IFE D10,[
MOVEI TT,1(T) ;UPDATE PURTBL
ROT TT,-PAGLOG-4
ADDI TT,(TT)
ROT TT,-1
TLC TT,770000
ADD TT,[430200,,PURTBL]
DPB T,TT ;T HAS 11 IN LOW TWO BITS
MOVEI TT,1(T) ;MEANS CAN PURIFY IF WE THINK ABOUT IT
LSH TT,11-PAGLOG
IOR TT,[4400,,400000]
.CBLK TT,
.LOSE 1000+%ENACR
] ;END OF IFE D10
IFN D10,[
HRRZ TT,HIXM
CORE TT,
.VALUE
] ;END OF IFN D10
JRST GTNPS1
SUBTTL FREE STORAGE SPACE EXPANSION
;;; THIS PORTION OF THE GARBAGE COLLECTOR DETERMINES WHETHER
;;; WE SHOULD JUST GRAB A NEW SEGMENT OF FREE STORAGE FOR SOME
;;; CONSER, OR DO A FULL-BLOWN GARBAGE COLLECTION. IT IS
;;; CONTROLLED BY PARAMETERS SETTABLE VIA (SSTATUS GCSIZE ...).
GCGRAB: MOVN R,D
JFFO R,.+1 ;DETERMINE WHICH SPACE WANTED MORE
SUBI F,NFF
MOVEI AR2A,1 ;MACRAK SEZ: GRAB JUST ONE
SKIPN FFY2
SETZ F,
JUMPE F,GCGRB1 ; ... SEZ MACRAK
MOVE D,SFSSIZ+NFF(F)
CAML D,GFSSIZ+NFF(F) ;CAN'T JUST GRAB IF ABOVE SIZE
JRST AGC1Q ; SPECIFIED FOR "FREE GRABBIES"
MOVE D,GFSSIZ+NFF(F)
CAMLE D,XFFS+NFF(F) ;CAN'T GRAB IF IT WOULD PUT
JRST AGC1Q ; US ABOVE THE MAXIMUM SIZE
GCGRB1: PUSH FXP,AR2A
PUSHJ P,GRABWORRY
POP FXP,AR1
JUMPGE AR2A,AGC1Q ;GO DO FULL-BLOWN GC AFTER ALL
IFN WHL,[
MOVE D,[-3,,GCWHL6]
MOVE R,GCWHO
TRNE R,1
.SUSET D
] ;END OF IFN WHL
JRST GCEND
;;; THIS ROUTINE WORRIES ABOUT GETTING A NEW IMPURE FREE STORAGE
;;; SEGMENT. (FOR PURE FREE STORAGE SEGMENTS, SEE GTNPSG.)
;;; MUST DO SPECIAL HACKERY FOR SYMBOL AND SAR SPACES, SINCE THEY
;;; REQUIRE MORE THAN ONE CONSECUTIVE SEGMENT. PRINTS OUT PRETTY
;;; MESSAGES IF GCGAG IS NON-NIL.
;;; MUST HAVE NOQUIT NON-ZERO AND ST/GCST PAGES IMPURE WHEN ENTERING!
GCWORRY: SUBI AR2A,(TT) ;ENTRY FOR GARBAGE COLLECTOR
ADDI AR2A,SEGSIZ-1 ;FIGURE OUT HOW MANY NEW SEGMENTS WE NEED
LSH AR2A,-SEGLOG
GRABWORRY:
Q$ HRRZ AR1,VMSGFILES
Q$ TLO AR1,200000
JUMPE F,.+2 ;ENTRY FOR GCGRAB
SKIPN GCGAGV ;MAYBE WE WANT A PRETTY MESSAGE?
SOJA AR2A,GCWOR2 ;IF NOT, DECR AR2A (SEE BELOW)
STRT 17,[SIXBIT \↑M;ADDING !\]
SOJG AR2A,GCWR0A ;AR2A GETS DECR'ED HERE, TOO!
STRT 17,[SIXBIT \A!\] ;KEEP THE ENGLISH GOOD
JRST GCWR0B
GCWR0A:
Q% MOVEI R,TYO
Q$ MOVEI R,$TYO
MOVEI TT,1(AR2A)
Q$ PUSH FXP,AR2A
IFE USELESS, MOVE C,@VBASE ;BASE DAMN WELL BETTER BE A FIXNUM
IFN USELESS,[
HRRZ C,VBASE
CAIE C,QROMAN
SKIPA C,(C)
PUSHJ P,PROMAN
] ;END OF IFN USELESS
PUSHJ P,PRINI9
Q$ POP FXP,AR2A
GCWR0B: STRT 17,[SIXBIT \ NEW !\]
STRT 17,@GSTRT9+NFF(F)
STRT 17,[SIXBIT \ SEGMENT!\]
SKIPE AR2A
STRT 17,[SIXBIT \S!\]
GCWOR2: SKIPE TT,IMSGLK
JRST GCWR2A ;JUMP IF ANY SEGMENTS AVAILABLE
JSP R,ALIMPG ;ELSE MUST GRAB A NEW PAGE
JRST GCWOR7
GCWR2A: LDB D,[SEGBYT,,GCST(TT)]
MOVEM D,IMSGLK ;CDR THE FREE SEGMENT LIST
MOVE D,FSSGLK+NFF(F) ;CONS NEW SEGMENT ONTO LIST
MOVEM TT,FSSGLK+NFF(F) ; OF SEGMENTS FOR THE
HRRZ R,BTBAOB ; PARTICULAR SPACE
HLL R,GCWORS+NFF(F)
LSH D,22-<SEGLOG-5>
GCWR2B: TLNE R,$FS+FX+FL+BN+HNK+DB+CX+DX .SEE GCWR2C
IORI D,(R) ;MAYBE ALLOCATE A BIT BLOCK FOR
IOR D,GCWORG+NFF(F) ; THE NEW SEGMENT FOR USE BY
MOVEM D,GCST(TT) ; GC IN MARKING CELLS
MOVE D,GCWORS+NFF(F) ;UPDATE ST ENTRY FOR THE
MOVEM D,ST(TT) ; NEW SEGMENT
MOVE D,FFS+NFF(F) ;ADD CELLS OF SEGMENT TO
LSH TT,SEGLOG ; THE FREE STORAGE
MOVEM D,(TT) ; LIST FOR THIS SPACE
MOVE D,[GCWORX,,1]
BLT D,LPROG9
HLL TT,GCWORN+NFF(F)
HRR GCWRX1,GCWORN+NFF(F)
HRRI GCWRX2,-1(GCWRX1)
JRST GCWRX1
GCWR2C: HRRZM TT,FFS+NFF(F)
TLNN R,$FS+FX+FL+BN+HNK+DB+CX+DX .SEE GCWR2B
JRST GCWR4Q
HRRZ TT,BTBAOB ;DECIDE WHETHER THIS BIT BLOCK
LSH TT,SEGLOG-5 ; LIES IN MAIN BIT BLOCK AREA
MOVEI D,-1(TT)
CAME D,MAINBITBLT
JRST GCWR3A
ADDI D,BTBSIZ ;YES - JUST UPDATE MAIN BLT
MOVEM D,MAINBITBLT ; POINTER FOR CLEARING
JRST GCWR3B ; BIT BLOCKS (SEE GCINBT)
GCWR3A: LSH TT,-SEGLOG ;ELSE AOS COUNT OF BIT BLOCKS
AOS GCST(TT) ; IN CURRENT BIT BLOCK SEGMENT
GCWR3B: MOVE TT,BTBAOB ;AOBJN THE BIT BLOCK
AOBJN TT,GCWOR4 ; ALLOCATION POINTER
SKIPE TT,IMSGLK ;FOO! OUT OF BIT BLOCKS!
JRST GCWR3F
JSP R,ALIMPG ;FOO FOO! NEED NEW PAGE!
JRST GCWFOO
GCWR3F: LDB D,[SEGBYT,,GCST(TT)]
MOVEM D,IMSGLK ;CDR LIST OF FREE SEGMENTS
MOVE D,[$XM,,QRANDOM] ;UPDATE ST AND GCST FOR
MOVEM D,ST(TT) ; NEW BIT BLOCK SEGMENT
MOVEI D,(TT) ;GCST ENTRY IS USED TO
LSH D,5 ; INDICATE HOW MANY
MOVEM D,GCST(TT) ; BLOCKS ARE IN USE
MOVE D,BTSGLK ;CONS NEW SEGMENT ONTO LIST
DPB D,[SEGBYT,,GCST(TT)] ; OF BIT BLOCK SEGMENTS
MOVEM TT,BTSGLK
LSH TT,5 ;CALCULATE NEW BIT BLOCK
HRLI TT,-SEGSIZ/BTBSIZ ; ALLOCATION POINTER
GCWOR4: MOVEM TT,BTBAOB
GCWR4Q: JUMPE F,GCWOR6
MOVEI TT,SEGSIZ ;UPDATE VARIOUS GC PARAMETERS
ADDM TT,NFFS+NFF(F)
ADDB TT,SFSSIZ+NFF(F)
CAMLE TT,XFFS+NFF(F) ;MUST STOP IF OVER MAX
SOJA AR2A,.+2 ;KEEP COUNT ACCURATE
GCWOR6: SOJGE AR2A,GCWOR2 ;ALSO STOP IF WE GOT ALL WE WANT
GCWOR7: JUMPE F,CPOPJ
SKIPN GCGAGV ;MAYBE WANT MORE PRETTY MESSAGE
POPJ P,
SKIPL AR2A
STRT 17,[SIXBIT \↑M; BUT DIDN'T SUCCEED!\]
STRT 17,[SIXBIT \ -- !\]
STRT 17,@GSTRT9+NFF(F)
STRT 17,[SIXBIT \ SPACE NOW !\]
Q% MOVEI R,TYO
IFN QIO,[
MOVEI R,$TYO
PUSH FXP,AR2A
HRRZ AR1,VMSGFILES
TLO AR1,200000
] ;END OF IFN QIO
MOVE TT,SFSSIZ+NFF(F)
IFE USELESS, MOVE C,@VBASE
IFN USELESS,[
HRRZ C,VBASE
CAIE C,QROMAN
SKIPA C,(C)
PUSHJ P,PROMAN
] ;END OF IFN USELESS
PUSHJ P,PRINI9
STRT 17,[SIXBIT \ WORDS!\]
Q$ POP FXP,AR2A
POPJ P,
;;; TYPICAL GCST ENTRIES FOR IMPURE SPACES
GCWORG: GCBMRK+GCBCDR+GCBCAR,, ;LIST
GCBMRK,, ;FIXNUM
GCBMRK,, ;FLONUM
DB$ GCBMRK,, ;DOUBLE
CX$ GCBMRK,, ;COMPLEX
DX$ GCBMRK,, ;DUPLEX
BG$ GCBMRK+GCBCDR,, ;BIGNUM
GCBMRK+GCBSYM,, ;SYMBOL
REPEAT HNKLOG, GCBMRK+GCBCDR+GCBCAR+GCBHNK,, ;HUNKS
GCBMRK+GCBSAR,, ;SAR
IFN .-GCWORG-NFF, WARN [WRONG LENGTH TABLE]
0 ;SYMBOL BLOCKS
;;; TYPICAL ST ENTRIES FOR IMPURE SPACES
GCWORS: LS+$FS,,QLIST ;LISP
FX,,QFIXNUM ;FIXNUM
FL,,QFLONUM ;FLONUM
DB$ DB,,QDOUBLE ;DOUBLE
CX$ CX,,QCOMPLEX ;COMPLEX
DX$ DX,,QDUPLEX ;DUPLEX
BG$ BN,,QBIGNUM ;BIGNUM
SY,,QSYMBOL ;SYMBOL
REPEAT HNKLOG, LS+HNK,,QHUNK1+.RPCNT ;HUNKS
SA+$XM,,QARRAY ;SAR
IFN .-GCWORS-NFF, WARN [WRONG LENGTH TABLE]
$XM,,QRANDOM ;SYMBOL BLOCKS
GCWFOO: STRT [SIXBIT \↑M;GLEEP#! OUT OF BIT BLOCKS!\]
JRST GCWOR7
GCWORX: ;EXTEND FREELIST THROUGH NEW SEGMENT
OFFSET 1-.
GCWRX1: HRRZM TT,.(TT) ;OCCUPIES A,B,C,AR1 - MUST SAVE AR2A
GCWRX2: ADDI TT,.
AOBJN TT,GCWRX1
JRST GCWR2C
LPROG9==:.-1
OFFSET 0
.HKILL GCWRX1 GCWRX2
GCWORN: -SEGSIZ+1,,1 ;LIST
-SEGSIZ+1,,1 ;FIXNUM
-SEGSIZ+1,,1 ;FLONUM
DB$ -SEGSIZ/2+1,,2 ;DOUBLE
CX$ -SEGSIZ/2+1,,2 ;COMPLEX
DX$ -SEGSIZ/2+1,,4 ;DUPLEX
BG$ -SEGSIZ+1,,1 ;BIGNUM
-SEGSIZ+1,,1 ;SYMBOL
REPEAT HNKLOG, -SEGSIZ/<2←.RPCNT>+1,,2←.RPCNT ;HUNKS
-SEGSIZ/2+1,,2 ;ARRAY SARS
IFN .-GCWORN-NFF, WARN [WRONG LENGTH TABLE]
-SEGSIZ/2+1,,2 ;SYMBOL BLOCKS
SUBTTL IMPURE PAGE GOBBLER
;;; ALLOCATE AN IMPURE PAGE FREE STORAGE USE
ALIMPG:
IFE D10,[
MOVE TT,HINXM ;MUST SAVE AR2A AND F FOR GCWORRY
SUBI TT,PAGSIZ
CAMGE TT,BPSH
] ;END OF IFE D10
IFN D10,[
MOVE TT,HIXM
ADDI TT,PAGSIZ
CAMLE TT,MAXNXM
] ;END OF IFN D10
JRST (R) ;NO PAGES LEFT - RETURN WITHOUT SKIP
IFE D10,[
MOVEM TT,HINXM ;ELSE UPDATE HINXM
MOVEI TT,1(TT)
LSH TT,11-PAGLOG
IOR TT,[4400,,400000]
.CBLK TT, ;SO GET THE NEW PAGE OF CORE
.LOSE 1000+%ENACR ;NO CORE AVAILABLE
MOVE TT,HINXM
MOVEI D,1(TT) ;COMPUTE A MAGIC BYTE POINTER
LSH D,-PAGLOG
ROT D,-4
ADDI D,(D)
ROT D,-1
TLC D,770000
ADD D,[430200,,PURTBL]
MOVEI C,1
DPB C,D ;UPDATE THE PURTBL
TLZ R,-1
CAIN R,GTCOR4+1 ;DON'T HACK IMSGLK FOR GETCOR
JRST 1(R)
] ;END OF IFE D10
IFN D10,[
MOVEM TT,HIXM
CORE TT,
.VALUE
MOVE TT,HIXM
] ;END OF IFN D10
LSH TT,-SEGLOG
10% ADDI TT,SGS%PG
MOVE C,IMSGLK ;UPDATE ST AND GCST, AND ADD
MOVE AR1,[$XM,,QRANDOM] ; NEW SEGMENTS TO IMSGLK LIST
MOVEI D,SGS%PG
ALIMP3: MOVEM AR1,ST(TT)
SETZM GCST(TT)
DPB C,[SEGBYT,,GCST(TT)]
MOVEI C,(TT)
SOJE D,ALIMP4
SOJA TT,ALIMP3
ALIMP4: MOVEM TT,IMSGLK ;WINNING RETURN SKIPS
JRST 1(R) ;EXITS WITH LOWEST NEW SEGMENT # IN TT
SUBTTL RECLAIM FUNCTION
IFN BIGNUM+USELESS,[
RECLAIM: HRRZS A ;SUBR 2
JUMPE A,CPOPJ ;GC A PARTICULAR SEXP
LOCKI
PUSHJ P,RECL1
MOVEI A,NIL
UNLKPOPJ
RECL1: SKOTT A,LS+PUR
2DIF JRST (TT),RECL9-1,QLIST .SEE STDISP
TLNE TT,HNK+VC+PUR ;DON'T RECLAIM VALUE CELLS!!! (OR HUNKS)
POPJ P, ; - ALSO DON'T RECLAIM PURE WORDS
PUSH P,A ;SAVE ARG
JUMPE B,RECL2 ;B=NIL => RECLAIM ONLY TOP LEVEL OF LIST
HLRZ A,(A) ;RECLAIM CAR
PUSHJ P,RECL1
RECL2: MOVE T,FFS
POP P,FFS
EXCH T,@FFS ;RECLAIM ONE CELL
MOVEI A,(T) ;AND THEN GO AFTER THE CDR
JRST RECL1
RECLFW: JUMPE B,RECL9A ;B=NIL => DON'T RECLAIM FULLWORDS
TLNE TT,$PDLNM ;DON'T RECLAIM PDL LOCATIONS!!!
POPJ P,
2DIF [MOVE T,(TT)]FFS-QLIST ;RECLAIM NUMBER
MOVEM T,(A)
2DIF [MOVEM A,(TT)]FFS-QLIST
POPJ P,
IFN BIGNUM,[
REBIG: MOVE T,FFB ;RECLAIM BIGNUM HEADER
EXCH T,(A)
MOVEM A,FFB
MOVEI A,(T) ;RECLAIM CDR OF BIGNUM
JRST RECL1
] ;END OF IFN BIGNUM
RECL9: JRST RECLFW ;FIXNUM
JRST RECLFW ;FLONUM
DB$ JRST RECLFW ;DOUBLE
CX$ JRST RECLFW ;COMPLEX
DX$ JRST RECLFW ;DUPLEX
BG$ JRST REBIG ;BIGNUM
RECL9A: POPJ P, ;SYMBOL
REPEAT HNKLOG, .VALUE ;HUNKS
POPJ P, ;RANDOM
POPJ P, ;ARRAY
IFN .-RECL9-NTYPES+1, WARN [WRONG LENGTH TABLE]
] ;END OF IFN BIGNUM+USELESS
IFN ITS,[
SUBTTL VALUE CELL AND SYMBOL BLOCK HACKERY
;;; ROUTINE TO GET MORE VALUE CELL SPACE.
;;; EXPANDS VALUE CELL SPACE BY GETTING NEXT PAGE IN THE HOLE
;;; LEFT FOR THIS PURPOSE, AND EXTENDING THE VALUE CELL FREELIST.
;;; IF NO PAGES LEFT IN THE HOLE, A LIST CELL IS USED.
XCTPRO
MAKVC3: HLLOS NOQUIT
NOPRO
SOSL NFVCP
JRST MAKVC4
PUSHJ P,CZECHI
PUSHJ P,CONS1
SETOM ETVCFLSP
JRST MAKVC1
MAKVC4: MOVE A,EFVCS
LSH A,11-PAGLOG
IOR A,[4400,,400000]
.CBLK A, ;SO GET THE NEW PAGE IN OUR CORE MAP
.LOSE 1000+%ENACR ;NO CORE AVAILABLE
MOVE A,EFVCS
MOVEM A,FFVC
LSH A,-SEGLOG
MOVE TT,[LS+VC,,QLIST]
REPEAT SGS%PG, MOVEM TT,ST+.RPCNT(A)
MOVSI TT,GCBMRK+GCBVC
REPEAT SGS%PG, MOVEM TT,GCST+.RPCNT(A)
LSH A,-PAGLOG+SEGLOG ;UPDATE PURTBL
ROT A,-4
ADDI A,(A)
ROT A,-1
TLC A,770000
ADD A,[430200,,PURTBL]
MOVEI TT,1
DPB TT,A
AOS TT,EFVCS
HRLI TT,-PAGSIZ+1
HRRZM TT,-1(TT)
AOBJN TT,.-1
HRRZM TT,EFVCS
MAKVC8: PUSHJ P,CZECHI
JRST MAKVC0
] ;END OF IFN ITS
;;; SYMBOL BLOCK COPYING ROUTINE - TRIGGERED BY PURE PAGE TRAP, OR EXPLICIT CHECK
;;; B POINTS TO OLD SYMBOL BLOCK
;;; LEAVES POINTER TO NEW SYMBOL BLOCK IN B
;;; CLOBBERS TT, LEAVES POINTER TO VALUE CELL IN A
LDPRG9: TLCA B,LDPARG ;FASLOAD CLOBBERING ARGS PROP
ARGCL7: TLC B,ARGCL3 ;ARGS CLOBBERING ARGS PROP
HRRZ A,(B)
JRST MAKVC6
MAKVC9: TLCA B,MAKVCX ;MAKVC CLOBBERING IN VALUE CELL
MAKVC5: PUSHJ P,AGC
BAKPRO
MAKVC6: SKIPN FFY2 ;COME HERE IF HRRM ABOVE CAUSES
JRST MAKVC5 ; A PURE PAGE TRAP - MUST COPY
MOVE TT,@FFY2 ; SYMBOL BLOCK FOR THAT SYMBOL
XCTPRO
EXCH TT,FFY2
NOPRO
HRLI A,777100 ;ASSUME COMPILED CODE NEEDS IT
MOVEM A,(TT) ; (THINK ABOUT THIS SOME MORE)
MOVE A,1(B)
MOVEM A,1(TT)
HRRZ A,(TT)
HRLM TT,@(P)
EXCH TT,B
HLRZ TT,TT
JRST (TT)
SUBTTL ALLOC FUNCTION
$ALLOC: CAIE A,TRUTH ;SUBR 1 - DYNAMIC ALLOC
JRST $ALLC5
SETO F, ;ARG=T => MAKE UP LIST
EXCH F,INHIBIT ;CROCKISH LOCKI - DOESN'T MUNG FXP
MOVNI R,NFF
$ALLC6: PUSH FXP,GFSSIZ+NFF(R) ;SAVE UP VALUABLE DATA
PUSH FXP,XFFS+NFF(R) ;LOCKI KEEPS IT CONSISTENT
PUSH FXP,MFFS+NFF(R)
AOJL R,$ALLC6
10% REPEAT 4, PUSH FXP,XPDL+.RPCNT
MOVEM F,INHIBIT ;EQUALLY CROCKISH UNLOCKI
PUSHJ P,CHECKI
PUSH P,R70
IFN ITS,[
MOVEI R,4
$ALLC9: POP FXP,TT
SUB TT,C2-1(R)
TLZ TT,-1
JSP T,FIX1A
MOVE B,(P)
PUSHJ P,CONS
MOVEI B,QREGPDL-1(R)
PUSHJ P,XCONS
MOVEM A,(P)
SOJG R,$ALLC9
] ;END OF IFN ITS
MOVEI R,NFF
$ALLC7: SKIPN SFSSIZ-1(R)
JRST $ALLC8 ;SPACE SIZE IS ZERO - IGNORE IT
POP FXP,TT
PUSHJ P,SSGP2A
PUSHJ P,NCONS
MOVEI B,(A)
POP FXP,TT
JSP T,FIX1A
PUSHJ P,CONS
MOVEI B,(A)
POP FXP,TT
JSP T,FIX1A
PUSHJ P,CONS
MOVE B,(P)
PUSHJ P,CONS
MOVEI B,QLIST-1(R)
CAIN B,QRANDOM
MOVEI B,QARRAY
PUSHJ P,XCONS
MOVEM A,(P)
JRST $ALLC4
$ALLC8: SUB FXP,R70+3 ;FLUSH GARBAGE
$ALLC4: SOJG R,$ALLC7
JRST POPAJ
$ALLC0: HRRZ A,(AR2A)
$ALLC5: JUMPE A,TRUE ;DECODE LIST OF PAIRS
HLRZ B,(A) ;ARG IS LIST OF SAME FORM AS
HRRZ AR2A,(A) ; A .LISP. (INIT) COMMENT
HLRZ C,(AR2A)
CAIL B,QREGPDL
CAILE B,QSPECPDL
JRST $ALLC3
MOVEI D,1←-1 ;SSPDLMAX
PUSHJ P,SSGP3$
JRST $ALLC0
$ALLC3: JSP R,SFRET
JRST $ALLC0
JRST $ALLC0
SETZ AR1,
MOVEI F,(C)
SKOTT C,LS
JRST $ALLC2
HRRZ AR1,(C)
HLRZ C,(C)
HLRZ F,(AR1)
SKIPE AR1
SKIPA AR1,(AR1)
SKIPA F,C
HLRZ AR1,(AR1)
$ALLC2: MOVEI D,3←-1 ;SSGCSIZE
PUSHJ P,SSGP3$
MOVEI C,(F)
MOVEI D,5←-1 ;SSGCMAX
PUSHJ P,SSGP3$
MOVEI C,(AR1)
MOVEI D,7←-1 ;SSGCMIN
PUSHJ P,SSGP3$
JRST $ALLC0
PGTOP BIB,[MEMORY MANAGEMENT STUFF]